home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1995 November / EnigmA AMIGA RUN 02 (1995)(G.R. Edizioni)(IT)[!][issue 1995-11][Skylink CD].iso / earcd / giochi / amigainf.lha / Inform / manuals / designers_manual.txt < prev   
Text File  |  1995-08-02  |  299KB  |  7,901 lines

  1. This manual describes the `Inform' compiler for adventure games.
  2.  
  3. Copyright (C) 1994 Graham Nelson
  4.  
  5.  
  6.  
  7.  
  8. The Inform Designer's Manual
  9. ****************************
  10.  
  11. Last updated 29/9/94
  12.  
  13.  
  14.  
  15. Introduction
  16. ************
  17.  
  18.      I will build myself a copper tower
  19.      With four ways out and no way in
  20.      But mine the glory, mine the power...
  21.      
  22.      -- Louis MacNeice (1907--1963), `Flight of the Heart'
  23.  
  24.  
  25.  
  26. Inform: an adventure game compiler
  27. ==================================
  28.  
  29. Inform is an adventure game compiler, and this is the book to read about
  30. it.
  31.  
  32. Infocom format `story files' (Adventure games, that is) can be played on
  33. almost any computer, ancient or modern, and interpreters which run them
  34. are widely available, from personal organisers to mainframes.  They
  35. represent probably the most portable form in which games can ever be
  36. written, as no alteration whatever is required to move a game from one
  37. model of computer to another.
  38.  
  39. Inform is not just a compiler but an `operating system' too: its library
  40. (a suite of standard game routines) allows designers to begin coding at
  41. once.  An Inform source file need not contain any of the parser code, or
  42. the running of the `game universe', only descriptions and exceptions to
  43. the usual rules.  This world is quite rich already, having over 80 verbs
  44. and an extensive grammar: the library understands rooms, objects,
  45. duplicates, containers, doors, things on top of other things, light,
  46. scoring, switching things on and off, opening, closing and locking
  47. things, entering things, travelling about in them and so forth.  The
  48. parser it uses (which can be entirely invisible to the designer, but is
  49. programmable and very flexible) is sophisticated enough to handle
  50. ambiguities, clarify its input by asking questions and to cope properly
  51. with plurals, vagueness, conversation, pronouns and the player becoming
  52. someone else in mid-game.
  53.  
  54. This manual makes occasional reference to the example games provided
  55. with Inform, at present `Advent' (a full version of the original
  56. mainframe Adventure, which contains a good deal of `everyday Inform'),
  57. `Toyshop' (a collection of unusual objects to play with) and `Balances'
  58. (a short story consisting of puzzles making great use of the parser's
  59. flexibility).  Try to get hold of these programs and preferably print
  60. them out.  There is also a `Shell' game consisting of the minimum code
  61. to get going, but all 14 lines of it are given anyway (*note
  62. Starting::.).
  63.  
  64.  
  65.  
  66. History of the Designer's Manual
  67. ================================
  68.  
  69. The text of this book has evolved from five earlier editions.  The old
  70. manual was in places rather technical, with a makeshift and sometimes
  71. defensive tone (`Inform is an easel, not a painting').  There were
  72. specifications of the run-time code format and literary critiques of
  73. games gone by: like an oven manual padded out with both a cookery book
  74. and a detailed plan of the gas mains.  This book contains just the
  75. instructions for the oven.
  76.  
  77. So there are three `companion volumes'.  `The Craft of Adventure' is an
  78. essay on the design of adventure games; `The Specification of the
  79. Z-Machine' covers the run-time format and Inform assembly language, its
  80. lowest level; and `The Inform Technical Manual' documents chiefly
  81. internals, for compiler maintenance and porting.
  82.  
  83. In trying to be both a tutorial and reference work in a budget of about
  84. 100 pages of A4, this book aims itself in style halfway between the two
  85. extremes of manual, Tedium and Gnawfinger's `Elements of Batch
  86. Processing in COBOL-66', third edition, and Mr Blobby's `Blobby Book of
  87. Computer Fun'.  (This makes some sections both leaden *and*
  88. patronising.)  I have tried to make every passage tell the truth, so
  89. that even early sections are reliable for reference purposes.  Passages
  90. which divert the main story, usually to tell the unexpurgated truth when
  91. this may just confuse the newcomer, are marked with warning exclamation
  92. marks, thus: `!!!!'.  Lengthy examples are left as exercises, with
  93. answers in the Appendix; which also contains a language specification,
  94. some reference lists, definitions of attributes and properties, and a
  95. large index.
  96.  
  97. The manual was converted to Texinfo format by Gareth Rees.
  98.  
  99.  
  100.  
  101. Copyright and copying permissions
  102. =================================
  103.  
  104. The copyright on Inform, the program and its source code, its example
  105. games and documentation (including this book) is retained by Graham
  106. Nelson, who asserts the moral right to be identified as its author.
  107. Having said this, I am happy for it to be freely distributed to anybody
  108. who wants a copy, provided that: (a) distributed copies are not
  109. substantially different from those archived by the author, (b) this and
  110. other copyright messages are always retained in full, and (c) no profit
  111. is involved.  However, a story file produced with the Inform compiler
  112. (and libraries) then belongs to its author, and may be sold for profit
  113. if desired, provided that its game banner contains the information that
  114. it was compiled by Inform, and the Inform version number.
  115.  
  116. At present, the best source for Inform material (executables of the
  117. compiler for different machines, source code, the library files and
  118. example games) is the anonymous ftp site `ftp.gmd.de', and its home
  119. directory is:
  120.  
  121.      /if-archive/infocom/compilers/inform
  122.  
  123.  
  124.  
  125. Credits and dedication
  126. ======================
  127.  
  128. Some of the ideas of Inform came from an incremental multi-player game
  129. called Tera, on the Cambridge University mainframe, written by Dilip
  130. Sequeira and the author in 1990 (whose compiler was called Teraform); in
  131. turn, this stole a little from David Seal and Jonathan Thackray's game
  132. assembler; which dates back to the late 1970s and was written for
  133. `Acheton', perhaps the first worthwhile game written outside America.
  134. Still, much of the Inform kernel derives ultimately from the `IEEE
  135. Computer' article `Zork: A Computerized Fantasy Simulation Game' by P.
  136. David Lebling, Marc S. Blank and Timothy A. Anderson; and more was
  137. suggested by Richard Tucker, among others.
  138.  
  139. With the advent of Inform 5 in mid-1994, I feel that the underlying
  140. language came to a satisfactory state.  The library files, however, may
  141. well go on being improved, since users can update these much more easily
  142. than the compiler (changes to which mean work for many people).  The
  143. present library files (release 5/4) are greatly enhanced from the Inform
  144. 5.2 files, but compatible with them (except in handling plural nouns and
  145. that the obselete attribute `autosearch' has been withdrawn).
  146.  
  147. The list of those who have helped the project along is legion: I should
  148. like to thank them all, porters, users and critics alike, but especially
  149. Volker Blasius, Paul David Doherty, Mark Howell, Bob Newell, Robert
  150. Pelak, Gareth Rees, Jørund Rian, Dilip Sequeira, Richard Tucker and
  151. Christopher Wichura.
  152.  
  153. One final word.  I should like to dedicate this book, impertinently
  154. perhaps, to our illustrious predecessors: Willie Crowther, Don Woods and
  155. the authors of Infocom, Inc.
  156.  
  157.      Graham Nelson
  158.      Magdalen College, Oxford
  159.      September 1994
  160.  
  161.  
  162.  
  163.  
  164. 1 Getting started
  165. *****************
  166.  
  167.  
  168.  
  169. 1.1 The `Shell' game
  170. ====================
  171.  
  172. The very first thing to try is to compile the `Hello Cruel World' game,
  173. a very short test file supplied with Inform.  If that compiles and runs
  174. properly (producing a short page of text, then finishing), try the
  175. following:
  176.  
  177.      Constant Story "SHELL";
  178.      Constant Headline "^An Interactive Skeleton^\
  179.          Copyright (c) 1994 by (your name here).^";
  180.      
  181.      Include "Parser";
  182.      Include "VerbLib";
  183.      
  184.      Object  Blank_Room "Blank Room"
  185.       with   description "An empty room."
  186.       has    light;
  187.      
  188.      [ Initialise;
  189.          location=Blank_Room;
  190.          "^^^^^Welcome to the shell...^^";
  191.      ];
  192.      
  193.      Include "Grammar";
  194.      end;
  195.  
  196. If this compiles, Inform is probably set up and working properly. It
  197. takes a short while to compile, because it `includes' three large
  198. standard files, containing a large amount of code.  (`Include' lines
  199. are also sometimes written `#include' to make C programmers feel more
  200. at home.)  The library files are:
  201.  
  202. `Parser'
  203.      The core of the game, and a full parser
  204.  
  205. `Verblib'
  206.      Routines for many game verbs, like `take'
  207.  
  208. `Grammar'
  209.      A grammar table to decode the player's input from
  210.  
  211. Together, they make up the `library'.  They can certainly be modified by
  212. designers, but great effort has gone into making sure the need hardly
  213. ever arises.
  214.  
  215. Apart from that, the code contains:
  216.  
  217.   1. strings giving the name of the game, and a copyright message, to be
  218.      printed out at the appropriate moments;
  219.  
  220.   2. a routine, called `Initialise', which is run when the game begins,
  221.      and simply sets where the player starts (in the obvious place!) and
  222.      prints a welcoming message;
  223.  
  224.   3. an object, to be the only room of the game.
  225.  
  226. The `Shell' game is very boring: there is nothing for the player to do
  227. but wait and quit.
  228.  
  229.  
  230.  
  231. 1.2 Making simple objects
  232. =========================
  233.  
  234. In Inform, everything is an object: rooms and things to be picked up,
  235. scenery, intangible things like mist and even some abstract ideas (like
  236. the direction `north').  More about this later: for now, here's a new
  237. object, to go under the `Blank_Room' definition:
  238.  
  239.      Nearby  cone "green cone"
  240.       with   name "green" "cone";
  241.  
  242. (`Nearby' just means it's an object inside the last thing declared as
  243. an `Object', in this case the Blank Room.)  A green cone now appears in
  244. the Blank Room.  The player can call it either `green cone', `cone' or
  245. even `green'.  It can be taken, dropped, looked at, looked under and so
  246. on.
  247.  
  248. This is still rather plain.  Examining the cone sees `nothing special
  249. about the green cone", for instance.  So we might extend the definition
  250. by:
  251.  
  252.      Nearby cone "green cone"
  253.        with name "green" "cone" "emerald",
  254.             initial "Nearby is an emerald green cone, one foot high.";
  255.  
  256. The `initial' message now appears when we arrive in the Empty Room.
  257. Taking things a little further...
  258.  
  259.      Nearby  cone "green cone"
  260.       with   name "green" "cone" "emerald" "marzipan",
  261.              initial "Nearby is an emerald green cone, one foot high.",
  262.              description "The cone seems to be made of emerald-coloured \
  263.                  marzipan."
  264.       has    edible;
  265.  
  266. (Note that the description is split across two lines: the `\' makes the
  267. message come out as one sentence without a huge space.)  Now if we
  268. examine the cone, we get its surprising `description': and the player
  269. is allowed to eat the cone.
  270.  
  271. !!!! `name', `description' and `initial' are examples of `properties',
  272. while `edible' is an `attribute': the difference is that the former
  273. have values, whereas the latter are just on or off.
  274.  
  275. So far, we're just filling in a form, and we could go much further doing
  276. this, but that wouldn't be much of an example.  Instead, some honest
  277. programming:
  278.  
  279.      Nearby  cone "green cone"
  280.       with   name "green" "cone" "emerald" "marzipan",
  281.              initial "Nearby is an emerald green cone, one foot high.",
  282.              description "The cone seems to be made of emerald-coloured \
  283.                  marzipan.",
  284.              after [;
  285.               Take: "Taken.  (Your hands are smeared with marzipan.)";
  286.               Drop: "The cone drops to the floor and sags a little.";
  287.              ],
  288.       has    edible;
  289.  
  290. The property `after' doesn't just have a string for a value: it has a
  291. routine of its own.  Now what happens is that when an action happens to
  292. the cone, the `after' routine is called to apply any special rules
  293. about the cone.  In this case, `Take' and `Drop' are the only actions
  294. tampered with: and the only effect is that the usual messages (`Taken.'
  295. `Dropped.') are replaced.
  296.  
  297. !!!! There's no real difference between routines like `Initialise',
  298. which are defined outside objects at the `top level', and routines
  299. inside objects like this `after' routine: except that outside routines
  300. have to have names, since they aren't identified by belonging to any
  301. particular object.
  302.  
  303.  
  304.  
  305. 1.3 Adding code to objects
  306. ==========================
  307.  
  308. Still, the cone doesn't actually do anything!  So here it is with a
  309. (completely unfair) puzzle added:
  310.  
  311.      Nearby  cone "green cone"
  312.       with   name "green" "cone" "emerald" "marzipan",
  313.              initial "Nearby is an emerald green cone, one foot high.",
  314.              description "The cone seems to be made of emerald-coloured \
  315.                  marzipan.",
  316.              before [;
  317.               Eat:
  318.                  if (random(100) <= 30) {
  319.                      deadflag = 1;
  320.                      "Unfortunately, you seem to be allergic to almonds.";
  321.                  }
  322.                  "You nibble at a corner of the cone.";
  323.              ],
  324.              after [;
  325.               Take: "Taken.  (Your hands are smeared with marzipan.)";
  326.               Drop: "The cone drops to the floor and sags a little.";
  327.              ],
  328.       has    edible;
  329.  
  330. The `before' routine is called before the player's intended action
  331. takes place.  So when the player tries typing, say, `eat the cone',
  332. what happens is: in 30% of cases, she dies of almond poisoning; and in
  333. the other 70%, she simply nibbles a corner of the cone (without actually
  334. consuming it completely).
  335.  
  336. !!!! Like many programming languages, Inform braces together blocks of
  337. code.  `deadflag' is a global variable, whose value does not belong to
  338. any particular object (or routine).  It is defined somewhere in the
  339. depths of the library: it's usually 0; setting it to 1 causes the game
  340. to be lost, and setting it to 2 causes a win.
  341.  
  342. In either case, the usual rule for the `Eat' action is never applied.
  343. This is because, although it isn't obvious from the code, the routine
  344. actually returns a value, true or false.  And the command
  345.  
  346.      "Unfortunately, you seem to be allergic to almonds.";
  347.  
  348. not only prints the message (together with a carriage return), but also
  349. returns true from the `before' routine.  Since the routine normally
  350. returns false, the library knows that something has happened to
  351. interrupt the usual rules of the game.
  352.  
  353.  
  354. 1.3.1 Exercise: the green cone
  355. ------------------------------
  356.  
  357. Extend the green cone so that it is described as sagging after it has
  358. been dropped back on the ground.  (You need a few more properties for
  359. this.)
  360.  
  361. *Note Answer (the green cone)::.
  362.  
  363.  
  364.  
  365.  
  366. 2 Ingredients and lexicon
  367. *************************
  368.  
  369. Properly speaking, `Inform' means the compiler and its language: whereas
  370. this book is chiefly about the `library' of code which comes with it.
  371. For most practical purposes this makes no difference - but it's worth
  372. remembering that in the last resort you can change almost anything about
  373. how the library works.
  374.  
  375.  
  376.  
  377. 2.1 The basic ingredients of a game
  378. ===================================
  379.  
  380. The basic ingredients of an Inform game are:
  381.  
  382.      *Objects*, *Routines*, *Actions* and *Grammar*.
  383.  
  384. We have already seen examples of Objects and Routines.  Actions happen
  385. in the course of play.  The main loop of a game looks like this:
  386.  
  387.   1. Ask the player to type something
  388.  
  389.   2. Parse this (i.e., decide what it means) and generate any actions it
  390.      calls for
  391.  
  392.   3. Work out the consequences of these actions and tell the player
  393.  
  394.   4. Worry about time passing by, and other things happening
  395.  
  396. a process which ends only in victory or death.  (In this respect it is
  397. unlike life.)
  398.  
  399. Probably the most complicated programming in any adventure game goes
  400. into the parser.  Inform's parser is fairly advanced, and is designed
  401. with the intention of being highly programmable at all levels to suit
  402. your game: so this manual will be returning to features of the parser
  403. again and again.  It isn't perfect by any means, but it does understand
  404. things like:
  405.  
  406.      throw three of the coins into the fountain
  407.      write funny on the lighted cube
  408.      take the sword and all the crowns
  409.      what is a grue
  410.      dwarf, give me the battleaxe
  411.  
  412. It also asks questions when it needs to, makes inferences from partial
  413. requests and tries to make good guesses when faced with ambiguous
  414. requests.  You can teach it new verbs and new forms of old ones: this is
  415. Grammar.  (The library starts with about 85 verbs, not counting
  416. synonyms.)
  417.  
  418. Until you need to start programming it, the parser sits in the
  419. background, and you need to know nothing about it.  But the parser is
  420. where Actions come from.  An Action can have up to two objects attached
  421. to it, and represents something which the player is trying to do.  For
  422. instance,
  423.  
  424.      Inv    Take sword    Insert gold_coin cloth_bag
  425.  
  426. are all actions.  (By this stage the game has reduced them to three
  427. numbers each, the action number and two object numbers: there's no text
  428. floating about.)
  429.  
  430. !!!! Actions are also sometimes produced as a knock-on effect by other
  431. actions, and they can also be produced by your own code: you can even
  432. create new actions altogether, which are treated no differently from the
  433. standard ones.
  434.  
  435.  
  436. 2.1.1 Exercise: actions
  437. -----------------------
  438.  
  439. Compile one of the supplied example games, say `Toyshop', with the
  440. `DEBUG' option defined (*note Debugging::.) so that you can use the
  441. special `actions' verb to see exactly what all the actions are as they
  442. happen.
  443.  
  444. *Note Answer (actions)::.
  445.  
  446.  
  447.  
  448. 2.2 Introduction to the Z-machine
  449. =================================
  450.  
  451. !!!! Inform can produce two kinds of game: `Standard' and `Advanced'.
  452. Code is in almost every case portable between these two forms, so that
  453. you can easily make a version each way from the same program.  The
  454. latter is better, but just in case you have a small computer (such as a
  455. personal organiser) or a very bad run-time interpreter, you might
  456. prefer the former.  Occasionally this manual will mention a difference
  457. between these forms.
  458.  
  459. !!!!! At this point, we should describe the imaginary machine, sometimes
  460. called the Z-machine (Z is for `Zork') which Inform compiles games for.
  461. An `interpreter' is a program which simulates this imaginary machine,
  462. so that it can run the game files that Inform produces: the same files
  463. will work on any interpreter on any machine.  Interpreters are
  464. available for very many machines indeed.  The Z-machine is, except in a
  465. few corners, a beautiful design and is described in great detail in the
  466. `Specification of the Z-Machine'.  For now, a few words about the
  467. memory map.  The memory of this imaginary computer is 128K long for
  468. Standard games and 256K long for advanced ones: the format is extremely
  469. well compressed, so this is actually quite a large memory.
  470.  
  471. !!!!! Numbers are stored in 16-bit words (2 bytes long), and are signed
  472. in the usual way, so they hold values -32768 <= n <= 32767 with the
  473. hexadecimal value `$ffff' being the same as -1.  The sign doesn't mean
  474. anything for addresses, of course, but there's a catch: given that a
  475. 2-byte number can only hold a value 0 <= n <= 65535, how can an address
  476. in a 128K or 256K memory map be held?  The answer is that there are two
  477. kinds of address: a `packed address' and a `byte address'.  A byte
  478. address is just an address in the bottom 64K of memory, and the
  479. Z-machine is arranged so that everything which could ever change is
  480. there: so these are the only addresses which matter very much.  Packed
  481. addresses are addresses divided by 2 (or by 4 in Advanced games), so
  482. they can only refer to even (divisible by four) locations in memory.
  483. They hold the addresses of long strings and routines, which Inform is
  484. careful always to put at even (divisible by four) locations.
  485.  
  486.  
  487.  
  488.  
  489. 3 Objects, properties and attributes
  490. ************************************
  491.  
  492.      Objects make up the substance of the world.  That is why they
  493.      cannot be composite.
  494.  
  495.      - Ludwig Wittgenstein (1889-1951), `Tractatus'
  496.  
  497.      ...making philosophical sense of change runs up against what seem
  498.      to be impossible philosophical difficulties.  Aristotle...
  499.      focuses on the central case of an object coming to have a property
  500.      that it formerly lacked.
  501.  
  502.      - Julia Annas, `Classical Greek Philosophy'
  503.  
  504.  
  505.  
  506. 3.1 The tree of objects
  507. =======================
  508.  
  509. The objects of the game form what is sometimes called a `tree', though a
  510. better analogy would be a forest, and anyway one usually draws the whole
  511. thing upside down and uses the language of `families' - calling them
  512. `children' and `parents' of each other.  Anyway, here's an example:
  513.  
  514.      Meadow
  515.        |
  516.      Mailbox  ->  Player
  517.        |            |
  518.      Note         Sceptre   ->   Cucumber  ->   Torch  ->   Magic Rod
  519.                                                   |
  520.                                                 Battery
  521.  
  522. This is a family tree, then: each object has a parent, a sibling and a
  523. child, though that object may be the special `nothing' object.  (The
  524. `Cucumber' has child `nothing', for instance.)
  525.  
  526. As the game goes on, objects move around: when an object moves, all its
  527. possessions (that is, children) go with it.  The Inform command to move
  528. an object is
  529.  
  530.      move object to new-owner;
  531.  
  532. and it must be emphasized that this prints nothing on the screen, and
  533. indeed does nothing except to change the tree above.
  534.  
  535. Inform provides special functions for reading this tree.
  536.  
  537.      `parent', `sibling' and `child'
  538.  
  539. all do the obvious things, and in addition there's a function called
  540. `children' which counts up how many children an object has (only
  541. children: grandchildren aren't counted).  For instance,
  542.  
  543.      parent   ( Mailbox ) = Meadow
  544.      children ( Player  ) = 4
  545.      child    ( Sceptre ) = 0
  546.      sibling  ( Torch   ) = Magic Rod
  547.  
  548. !!!! `nothing' isn't really an object: it's just a convenient name for
  549. the number 0, which is the object number meaning `no such object'.  It
  550. isn't a good idea to meddle with `nothing', or to apply functions like
  551. `parent' to it, but then there's never any need.
  552.  
  553. !!!!! When an object is added to the possessions held by another, it
  554. appears at the end of the list.  Thus, the eldest child is first in the
  555. list and the youngest is last.  Inform also provides functions
  556.  
  557. `youngest'
  558.      end of list of possessions
  559.  
  560. `eldest'
  561.      same as `child'
  562.  
  563. `younger'
  564.      same as `sibling', i.e., rightwards in the picture
  565.  
  566. `elder'
  567.      reverse of `sibling', i.e., leftwards in the picture
  568.  
  569.  
  570.  
  571. 3.2 Attributes
  572. ==============
  573.  
  574. Objects have more to them than just where they are in the tree.  They
  575. also have collections of variables attached to them.
  576.  
  577. Firstly, there are flags, called `attributes', which can be either set
  578. or clear.  These might be such conditions as `giving light', `currently
  579. worn' or `is one of the featureless white cubes'.  Attributes all have
  580. names, which are a single word: like `light', for instance, which
  581. indicates that something is giving off light.  There are about 30
  582. defined by the library.  They can be tested with a condition like
  583.      if (obj has locked) "But it's locked!";
  584.  
  585. and can be set with the `give' command.  So, for instance,
  586.  
  587.      give brass_lantern light;
  588.      give iron_door locked;
  589.  
  590. and they can be taken away with
  591.  
  592.      give brass_lantern ~light;
  593.      give fake_coin ~scored;
  594.  
  595. the `~' sign (or tilde) standing for negation.  In fact you can give or
  596. take many at one go, so for instance
  597.  
  598.      give wooden_door open openable ~locked;
  599.  
  600. !!!! You can make your own attributes with a directive like
  601.  
  602.      Attribute offered_to_ogre;
  603.  
  604. at the start of the program.  (A `directive' is a command to Inform
  605. directly, and happens at compile-time: not something in a routine which
  606. is to happen in the course of play.)
  607.  
  608. !!!!! In Standard games there are few spare attributes available because
  609. the library takes most of them.  To get around this limit there's a
  610. convenient dodge.  It sometimes happens that an attribute is only
  611. meaningful for a particular kind of object: for instance, `spell has
  612. been read' might only be meaningful for a `scroll'.  With care,
  613. therefore, one may re-use the same attribute to have different meanings
  614. for different kinds of object. The syntax to declare that an attribute
  615. is being reused is
  616.  
  617.      Attribute <new> alias <old>;
  618.  
  619. Thereafter Inform will treat the new and old attribute names as
  620. referring to the same attribute: it's up to the programmer to make sure
  621. this does not lead to inconsistencies.  (The library already indulges in
  622. a certain amount of this chicanery.)
  623.  
  624.  
  625.  
  626. 3.3 Properties
  627. ==============
  628.  
  629. Secondly, there are `properties'.  These are far more elaborate, and not
  630. every object has every property.  For instance: not every object has the
  631. `door_to' property (it holds the place a door leads to, so things other
  632. than doors don't usually have it).  The current value of a property is
  633. got at by constructions like:
  634.  
  635.      iron_door.door_to
  636.      crystal_bridge.door_to
  637.      green_cone.before
  638.      diamond.initial
  639.  
  640. You can read the value of `door_to' for something like the `diamond',
  641. and you'll just get a dull value like `nothing', but you can't write to
  642. it: that is, you can't change `diamond.door_to' unless you declared a
  643. `door_to' property for it.
  644.  
  645. !!!! You can also define your own properties (again, subject to
  646. availability, because the library claims many of them).
  647.  
  648.      Property door_to;
  649.      Property article "a";
  650.      Property blorple_routine $ffff;
  651.  
  652. are all examples of the `Property' directive.  In the case of
  653. `article', we are saying that the value `"a"' should be the default
  654. value for any object which doesn't declare an `article'.
  655.  
  656. !!!!! Properties can also `alias'.  They can also be declared as `long'
  657. or `additive', which is a complicated matter: basically, we'll come to
  658. `additive' when discussing classes, and properties which might start as
  659. small numbers (less than 256) and be changed into large ones in play,
  660. ought to be declared as `long'.
  661.  
  662. As will be seen from examples, a property value can be many things: a
  663. string like `"frog"', a number such as `$ffff' (this is the Inform way
  664. of writing numbers in hexadecimal), an object or a routine.  You can
  665. change the current value by something like
  666.  
  667.      location.door_to = hall_of_mists;
  668.      brass_lantern.short_name = "dimly lit brass lantern";
  669.      grenade.time_left = 45;
  670.  
  671. *WARNING:* The game may crash at run-time if you attempt to write to a
  672. property field which an object hasn't got.  So although you can read an
  673. undeclared property (you just get the default value), you can't write to
  674. one.  (Also, you can't extend a property beyond its length: see below.)
  675.  
  676. !!!! The Inform language does not have types as such, and strings and
  677. routines are stored as numbers: as their addresses inside the virtual
  678. machine, in fact.  This means that Inform thinks
  679.  
  680.      "Hello there" + 45 + 'a'
  681.  
  682. is a perfectly sensible calculation.  It's up to you to be careful.
  683.  
  684. !!!!! A property can hold more than just one number (be it interpreted
  685. as a string, a routine or whatever): it can hold a small array of
  686. numbers.  In Standard games it can have four numbers (8 bytes' worth),
  687. and in Advanced games 32 (64 bytes).  For instance, an entry in an
  688. object definition might read
  689.  
  690.      found_in Marble_Hall Arched_Passage Stone_Stairs,
  691.  
  692. storing a sequence of three values (all objects) in the `found_in'
  693. property.  To read or write to this array, you need to know its (byte)
  694. address and its length.  The operators
  695.  
  696.      `object.&property' and `object.#property'
  697.  
  698. tell you these.  (Be warned: `object.#property' tells you the number of
  699. bytes, not the number of words.)  If you give a property more than 8
  700. bytes of data in a Standard game, Inform warns you and takes only the
  701. first 8, but does not cause an error: this is so that, say,
  702.  
  703.      Object  ...
  704.       with   name "radio" "wireless" "transistor" "portable" "stereo" "tranny",
  705.              ...
  706.  
  707. will compile either way (but the last two synonyms for `"radio"' will
  708. not enter the dictionary if it's being compiled in Standard form, since
  709. a name takes two bytes).
  710.  
  711.  
  712. 3.3.1 Exercise: property addresses
  713. ----------------------------------
  714.  
  715. !!!!! Use the `object.&property' construction to find out whether the
  716. object in variable `obj' has the `door_to' property defined or not.
  717.  
  718. *Note Answer (property addresses)::.
  719.  
  720.  
  721.  
  722. 3.4 Making object definitions
  723. =============================
  724.  
  725. Time to make some object definitions.  A typical object definition looks
  726. something like:
  727.  
  728.      Object  trapdoor "hinged trapdoor" attic
  729.       with   name "hinged" "trap" "door" "trapdoor",
  730.              when_open "A hinged trapdoor in the floor stands open, and \
  731.                  light streams in from below.",
  732.              when_closed "There is a closed trapdoor in the middle of the \
  733.                  floor.",
  734.              door_to house,
  735.              door_dir d_to,
  736.       has    door static open light openable;
  737.  
  738. This is the conventional way to lay out an `Object' declaration: with
  739. the header first, then `with' a list of properties and their starting
  740. values, finishing up with the attributes it initially `has'.
  741.  
  742. `trapdoor' is the name given to the object in the program, and it
  743. becomes a constant from then on (whose value is the number of the
  744. object).  The `attic' is the object which the `trapdoor' starts out
  745. belonging to (as any player of `Curses' will know).  Some objects start
  746. out not belonging to anything (rooms, for example, or treasures which
  747. only appear half-way through).  You can declare these as belonging to
  748. `nothing', but it's better just to miss this out altogether:
  749.  
  750.      Object  trapdoor "hinged trapdoor"
  751.       with   ...
  752.  
  753. If you do declare an object already belonging to another, as above, then
  754. the other object must already have been defined.  (This is no real
  755. restriction, and ensures that you can't set up a `loop' - one in another
  756. in a third in the first, for instance.)
  757.  
  758. Objects can also be declared, in an identical way, by the `Nearby'
  759. directive.  The only difference is that no initial-owner object can be
  760. given; it starts out belonging to the last thing declared as an
  761. `Object'.  For example, in
  762.  
  763.      Object  hillside "Panoramic Hillside"
  764.       with   ...
  765.      
  766.      Nearby  scenery "scenery"
  767.       with   ...
  768.  
  769. the `hillside' is a room to which the `scenery' will belong.
  770. Otherwise, `Nearby' is the same as `Object', and this is just a
  771. convenience to make it easier to move things around in Inform code by
  772. cutting definitions out and pasting them in elsewhere.
  773.  
  774. Some properties of objects should be routines.  For instance, an object
  775. can have a `describe' property which is a routine to print out a
  776. description of it.
  777.  
  778. These could just be listed as names of routines, but usually the actual
  779. routine is written out then and there as the property value.  For
  780. instance, in the classic Adventure object
  781.  
  782.      Nearby  tasty_food "tasty food"
  783.       with   description "Sure looks yummy!",
  784.              initial "There is tasty food here.",
  785.              name "food" "ration" "rations" "tripe" "yummy" "tasty"
  786.                  "delicious" "scrumptious",
  787.              after [;
  788.               Eat: "Delicious!";
  789.              ],
  790.              article "some"
  791.       has    edible;
  792.  
  793. the `after' property does not name a routine but instead defines it.
  794. No name is needed or given for the routine.  (The semicolon after the
  795. `[' is needed to show that the routine has no local variables.)
  796.  
  797. The routine must end with either `],' or `];'.  If `],' the object
  798. definition can resume where it left off, with further properties.  (If
  799. it ends with `];', then the object definition ends where the routine
  800. finishes.)
  801.  
  802. !!!! The rules for embedded routines are not quite the same as those for
  803. ordinary routines.  By default, embedded routines return `false', or 0
  804. (instead of `true', or 1, which other routines return by default).
  805. Also, the handy shorthand:
  806.  
  807.      Action [, Action2 ...] : ...some code...
  808.  
  809. is provided, which executes the code only if the action being considered
  810. is the one named.
  811.  
  812. !!!!! It actually does this by setting a special variable called
  813. `sw__var' to the action number: when it compiles `Action1:' it just
  814. compiles an `if' statement which sees whether `sw__var' has value
  815. `Action1'.
  816.  
  817. !!!! Properly speaking, the full syntax of the header is
  818.  
  819.      `Object' OBJ-NAME-1 ... OBJ-NAME-N `"short name"' [PARENT-OBJ]
  820.      *or* `Nearby' OBJ-NAME-1 ... OBJ-NAME-N `"short name"'
  821.      *or* `Class' CLASS-NAME
  822.  
  823. and the parent object must have already been defined.  A `Class'
  824. definition is very like an object definition, and will be discussed
  825. later on.  The syntax for an object, then, is
  826.  
  827.      HEADER [`,']
  828.        `class' CLASS-1 ... CLASS-N [`,']
  829.        `with'  PROPERTY-NAME-1 VALUE-1 ... VALUE-N`,'
  830.              PROPERTY-NAME-2 VALUE-1 ... VALUE-N`,'
  831.              ...
  832.              PROPERTY-NAME-N VALUE-1 ... VALUE-N [`,']
  833.        `has'   ATT-1 ... ATT-N
  834.  
  835. Although it's conventional to write `class', `with' and `has' in this
  836. order, actually they can be in any order and any or all can be omitted
  837. altogether: and the commas in square brackets `[,]' are optional in
  838. between these fields.  (The classes listed under `class' are those
  839. which the object inherits from.)
  840.  
  841. !!!! One property is treated differently from the others, and this is
  842. the special property `name'.  Its data must be a list of English words
  843. in double-quotes, as in all the above examples.  (Probably the most
  844. annoying restriction of Standard games is that this means only 4 names
  845. at most can be accommodated in that format: you get up to 32 in
  846. Advanced games.)  It will probably confuse the parser if any of these
  847. names is something like `"my"', `"the"', `"all"', `"except"' or
  848. `"this"'.  Numbers can safely be used, however.
  849.  
  850. !!!!! In fact, `name' contains a list of byte addresses of dictionary
  851. words.  A quick way to print out the first word in the `name' list is
  852. therefore
  853.  
  854.      print_addr obj.name;
  855.  
  856. !!!!! The attributes and so on can be taken away as well as added, thus:
  857.  
  858.       ...
  859.       has    light ~scored;
  860.  
  861. which is sometimes useful to over-ride an inheritance from a class
  862. definition.
  863.  
  864. !!!!! A final curiosity of the `Object' syntax is that objects can be
  865. given more than one name.  This is a hangover from much earlier days of
  866. Inform, to do with re-using the same physical object in different
  867. logical ways, something which the author does not commend to anyone.
  868.  
  869.  
  870.  
  871.  
  872. 4 Places, scenery and the map
  873. *****************************
  874.  
  875.      It was a long cylinder of parchment, which he unrolled and spread
  876.      out on the floor, putting a stone on one end and holding the
  877.      other.  I saw a drawing on it, but it made no sense.
  878.  
  879.      - John Christopher, `The White Mountains'
  880.  
  881.      And if no piece of chronicle we prove,
  882.      We'll build in sonnets pretty rooms;
  883.      As well a well wrought urn becomes
  884.      The greatest ashes, as half-acre tombs.
  885.      
  886.      -- John Donne (1571?--1631), `The Canonization'
  887.  
  888.  
  889.  
  890. 4.1 Joining rooms together
  891. ==========================
  892.  
  893. Back to our example.  Throw away the old `blank room' and replace it by
  894.  
  895.      Object  Square_Room "Square Room"
  896.       with   description "A broad, square room, ten yards on a side, \
  897.                  floored with black and white chequered tiles."
  898.       has    light;
  899.  
  900. (We also have to change the `Initialise' routine to make this the place
  901. where the player begins, since the Blank Room no longer exists.)
  902.  
  903. Like the blank room, this one has `light'.  (If it didn't, the player
  904. would never see it, since it would be dark, and the player hasn't yet
  905. been given a lamp or torch of some kind.)  So where is the light coming
  906. from?
  907.  
  908.      Nearby  chandelier "crystal chandelier"
  909.       with   name "crystal" "chandelier",
  910.              initial "A crystal chandelier hangs from far above, casting \
  911.                  light in little rainbows across the floor.",
  912.              description "The crystal is beautiful cut-glass."
  913.       has    static;
  914.  
  915. This is part of the fittings, hence the `static' attribute (which means
  916. it can't be taken or moved).  But what about the rainbows?
  917.  
  918.      Nearby  rainbows "rainbows"
  919.       with   name "rainbow" "rainbows",
  920.              description "Caused by diffraction, or something like that - \
  921.                  you were never very good at physics."
  922.       has    scenery;
  923.  
  924. Being `scenery' makes the object not only static but also not described
  925. by the game unless actually examined by the player.  A true
  926. perfectionist might alter it to:
  927.  
  928.      Nearby  rainbows "rainbows"
  929.       with   name "rainbow" "rainbows",
  930.              description "Caused by diffraction, or something like that - \
  931.                  you were never very good at physics.",
  932.              before [;
  933.               Take, Push, Pull, Turn: "But the rainbows are made of light.";
  934.              ],
  935.       has    scenery;
  936.  
  937. Let us now add a second room:
  938.  
  939.      Object  Corridor "Sloping Corridor"
  940.       with   description "This corridor slopes upward and out of the \
  941.                  square room.",
  942.              d_to Square_Room, s_to Square_Room,
  943.              u_to "The slope becomes impossibly steep, and you retreat.",
  944.              cant_go "The corridor runs up and down."
  945.       has    light;
  946.  
  947. and extend the Square Room to:
  948.  
  949.      Object  Square_Room "Square Room"
  950.       with   description "A broad, square room, ten yards on a side, \
  951.                 floored with black and white chequered tiles.  A doorway \
  952.                 in the centre of the north side opens onto a rising \
  953.                 corridor.",
  954.              u_to Corridor,
  955.              n_to Corridor
  956.       has    light;
  957.  
  958. The player can now go from one to the other.  The properties `u_to',
  959. `d_to', `n_to' (and so on) declare what lies in the directions `up',
  960. `down', `north' (and so on).  If they aren't declared, one cannot go
  961. that way.  Notice that they can be either a room or a message which is
  962. printed if the player tries to go in the given direction.
  963.  
  964. In the Square Room, if the player tries to go, say, east, she gets a
  965. message along the lines of `You can't go that way.', which is not very
  966. helpful.  In the Corridor, the `cant_go' message is printed instead.
  967. (In fact, as is often the case with properties, instead of giving an
  968. actual message you can instead give a routine to print one out, so that
  969. what is printed varies with circumstances.)
  970.  
  971. Map connections are all one-way, in themselves: they just happen to be
  972. defined here so that they appear two-way.
  973.  
  974.  
  975.  
  976. 4.2 Adding code to rooms
  977. ========================
  978.  
  979. Rooms also have rules of their own.  We might write:
  980.  
  981.      Object  Corridor "Sloping Corridor"
  982.       with   description "This corridor slopes upward and out of the \
  983.                 square room: the floor underfoot is a little sticky.",
  984.              d_to Square_Room, s_to Square_Room,
  985.              u_to "The slope becomes impossibly steep, and you retreat.",
  986.              cant_go "The corridor runs up and down.",
  987.              before [;
  988.               Take:
  989.                  if (noun == cone)
  990.                      "The cone seems to be stuck to the floor here.";
  991.              ],
  992.       has    light;
  993.  
  994. and now the cone (if dropped there) cannot be taken from the floor of
  995. the Sloping Corridor.  The variables `noun' and `second' hold the first
  996. and second nouns supplied with an action.  Rooms have `before' and
  997. `after' routines just as objects do.
  998.  
  999. !!!!! Sometimes the room may be a different one after the action has
  1000. taken place.  The `Go' action, for instance, is offered to the `before'
  1001. routine of the room which is being left, and the `after' routine of the
  1002. room being arrived in.  For example:
  1003.  
  1004.              after [;
  1005.               Go:
  1006.                  if (noun==in_obj)
  1007.                      print "How grateful you are to get out of the \
  1008.                              rain...^";
  1009.              ],
  1010.  
  1011. will print the message when the room is entered via the `in' direction.
  1012. (Note that the message is printed with the `print' command.  This means
  1013. that it does not automatically return true: in fact, it returns false,
  1014. so the game knows that the usual rules still apply.  Also, no new-line
  1015. is printed automatically: but the `^' symbol means `print a new-line',
  1016. so one is actually printed.)
  1017.  
  1018. !!!! Directions (such as `north') are objects called `n_obj', `s_obj'
  1019. and so on: in this case, `in_obj'.  (They are not to be confused with
  1020. the property names `n_to' and so on.)  Moreover, you can change these
  1021. directions (as far as Inform is concerned, only things in the special
  1022. object `compass' can be directions).
  1023.  
  1024.  
  1025. 4.2.1 Exercise: world colours
  1026. -----------------------------
  1027.  
  1028. !!!! In the first millenium A.D., the Mayan peoples of the Yucatán
  1029. Peninsula had `world colours' white (*sac*), red (*chac*), yellow
  1030. (*kan*) and black (*chikin*) for what we call the compass bearings
  1031. north, east, south, west (for instance west is associated with
  1032. `sunset', hence black, the colour of night). Implement this.
  1033.  
  1034. *Note Answer (world colours)::.
  1035.  
  1036.  
  1037. 4.2.2 Exercise: reflecting the map
  1038. ----------------------------------
  1039.  
  1040. !!!! (Cf. `Trinity'.)  How can the entire game map be suddenly
  1041. east-west reflected?
  1042.  
  1043. *Note Answer (reflecting the map)::.
  1044.  
  1045.  
  1046. 4.2.3 Exercise: reflecting directions
  1047. -------------------------------------
  1048.  
  1049. !!!!! Even when the map is reflected, there may be many room
  1050. descriptions referring to `east' and `west' by name.  Reflect these too.
  1051.  
  1052. *Note Answer (reflecting directions)::.
  1053.  
  1054.  
  1055.  
  1056.  
  1057. 5 Causing actions and making new ones
  1058. *************************************
  1059.  
  1060.      Only the actions of the just
  1061.      Smell sweet and blossom in their dust.
  1062.      
  1063.      -- James Shirley (1594--1666), `The Contention of Ajax and Ulysses'
  1064.  
  1065.      ...a language obsessed with action, and with the joy of seeing
  1066.      action multiply from action, action marching relentlessly ahead
  1067.      and with yet more actions filing in from either side to fall into
  1068.      neat step at the rear, in a long straight rank of cause and
  1069.      effect, to what will be inevitable, the only possible end.
  1070.  
  1071.      - Donna Tartt, `The Secret History'
  1072.  
  1073.  
  1074.  
  1075. 5.1 Causing actions to happen
  1076. =============================
  1077.  
  1078. One often wants to simulate the effect of a player typing something.
  1079. For instance, in the Pepper Room the air is full of pepper and every
  1080. turn the player sneezes and drops something at random.  If the code to
  1081. do this simply removes an object and puts it on the floor, then it might
  1082. accidentally provide a solution to a problem like `the toffee apple
  1083. sticks to your hands so you can't drop it'.
  1084.  
  1085. This can at least be coded like this:
  1086.  
  1087.      You sneeze convulsively, and lose your grip on the toffee apple...
  1088.      The toffee apple sticks to your hand!
  1089.  
  1090. which (though not ideal) is much better.  As an example, here is another
  1091. piece of scenery to clutter up the tiny map so far:
  1092.  
  1093.      Object  low_mist "low mist"
  1094.       with   name "low" "swirling" "mist", article "the",
  1095.              initial "A low mist swirls about your feet.",
  1096.              description "It carries the unmistakable odour of cinnamon.",
  1097.              found_in  Square_Room  Corridor,
  1098.              before [;
  1099.               Smell: <<Examine self>>;
  1100.              ],
  1101.       has    static;
  1102.  
  1103. This mist is found in both the Square Room and the Corridor: note that
  1104. the `found_in' property has a list of places as its value.
  1105.  
  1106. The player will find that smelling the mist produces the same message as
  1107. looking at it.  The command
  1108.  
  1109.      <<Examine self>>;
  1110.  
  1111. causes the game to behave exactly as if the player had typed `examine
  1112. the mist' at the keyboard: that is, the `Examine' action happens,
  1113. applied to the `low_mist' object.  (`self' always means the object
  1114. whose routine this is.  In this case, it's really a bit pointless since
  1115.  
  1116.      <<Examine low_mist>>;
  1117.  
  1118. does just the same thing.)  After going through the business of
  1119. examining the mist, the routine then returns `true', or 1 (in this case,
  1120. so that the normal rules for smelling something are stopped in their
  1121. tracks).
  1122.  
  1123. If instead
  1124.  
  1125.      <Examine self>;
  1126.  
  1127. had been used, the same would have happened, but the routine would not
  1128. have been returned from.  So the mist would be examined; and then the
  1129. routine for `Smell' would resume, and since there's nothing more to it,
  1130. it would return false; whereupon the library's usual rules would make
  1131. it say something like `You smell nothing unusual.'.
  1132.  
  1133. All actions can be written this way:
  1134.  
  1135.      <Look>;  <<ThrowAt cone chandelier>>;
  1136.  
  1137. will, for instance, look around, then behave as if the player had asked
  1138. to throw the cone at the chandelier, then return true.
  1139.  
  1140. !!!! Internally, actions like `Look', `ThrowAt' and `Take' are stored
  1141. as numbers, and the number associated with an action can be got at by
  1142. `x = ##Take;' for instance.  The variable `action' holds the current
  1143. action number and sometimes it's convenient to use this directly.  For
  1144. instance, imagine a mirror hung very far above the player.  Given:
  1145.  
  1146.              before [;
  1147.                  if (action==##Examine) rfalse;
  1148.                  "The mirror is too high up, out of reach.";
  1149.              ]
  1150.  
  1151. the player will only be able to examine the mirror, and nothing else.
  1152. This prevents the library from ever saying something like `You push the
  1153. mirror but nothing happens.', which would be misleading.
  1154.  
  1155. !!!! An action corresponds to a routine somewhere which actually carries
  1156. out the looking, throwing at, taking and so forth.  (Well, in fact there
  1157. are also some special actions called `fake actions' which don't
  1158. correspond to such routines, as we shall come to later.)  These have the
  1159. same name as the action with `Sub' (short for `subroutine') on the end:
  1160. so, `TakeSub' for instance.
  1161.  
  1162.  
  1163.  
  1164. 5.2 Actions defined by the library
  1165. ==================================
  1166.  
  1167. !!!! The actions implemented by the library are in three groups.  The
  1168. useful ones are in groups 2 and 3:
  1169.  
  1170.   1. Quit, Restart, Restore, Verify, Save, ScriptOn, ScriptOff,
  1171.      Pronouns, Score, Fullscore, LMode1, LMode2, LMode3, NotifyOn,
  1172.      NotifyOff;
  1173.  
  1174.   2. Inv, InvTall, InvWide, Take, Drop, Remove, PutOn, Insert, Transfer,
  1175.      Empty, Enter, Exit, GetOff, Go, GoIn, Look, Examine, Give, Show,
  1176.      Unlock, Lock, SwitchOn, SwitchOff, Open, Close, Disrobe, Wear, Eat;
  1177.  
  1178.   3. Yes, No, Burn, Pray, Wake, WakeOther [person], Kiss, Think, Smell,
  1179.      Listen, Taste, Touch, TouchThing, Dig, Cut, Jump [jump on the
  1180.      spot], JumpOver, Tie, Drink, Fill, Sorry, Strong [swear word],
  1181.      Mild [swear word], Attack, Swim, Swing [something], Blow, Rub,
  1182.      Set, WaveHands [ie, just "wave"], Wave [something], Pull, Push,
  1183.      PushDir [push something in a direction], Turn, Squeeze, LookUnder
  1184.      [look underneath something], Search, ThrowAt, Answer, Buy, Ask,
  1185.      Sing, Climb, Wait, Sleep
  1186.  
  1187. Of course, the player can type all manner of things to get these.  For
  1188. instance, `take off shirt' and `remove the shirt' both cause the
  1189. `Disrobe' action.  Your code can ignore this complication.
  1190.  
  1191. !!!!! Group 1 actions are called `meta' - they are outside the game
  1192. proper, and your code is unable to interfere with them.  (If you want a
  1193. room where the game can't be saved, as for instance `Spellbreaker'
  1194. cunningly does, you'll have to tamper with `SaveSub' directly, using a
  1195. `Replace'd routine.)
  1196.  
  1197. Although all actions call the `before' routines, not all of them bother
  1198. to check `after' routines.  For instance, since the built-in `SmellSub'
  1199. routine just says `You smell nothing out of the ordinary', there would
  1200. be no point calling `after' routines - nothing, after all, has been
  1201. done.  (These are the group 3 actions above.)
  1202.  
  1203. !!!! The ones which actually do something, and call `after', are:
  1204.  
  1205.      Inv, Take, Drop, Remove, PutOn, Insert, Exit, Go, Look, Examine,
  1206.      Unlock, Lock, SwitchOn, SwitchOff, Open, Close, Disrobe, Wear, Eat,
  1207.      Search.
  1208.  
  1209. !!!!! Some other group 2 actions use these `after' routines indirectly
  1210. - if the player empties a sack out onto the floor, this is deemed to be
  1211. a sequence of `Drop' actions, for instance, and if a sack is emptied
  1212. into a packing case this is considered a multiple insertion.
  1213.  
  1214. !!!!! `Search' (the searching or looking-inside-something action) is a
  1215. slightly special case between groups 2 and 3.  It never actually does
  1216. anything beyond printing messages.  What happens is that if it would be
  1217. sensible to look inside the object (i.e., if it's an open or
  1218. transparent container and there is light), `after' is called
  1219. beforehand.  In this way you can use `before' to trap searching of
  1220. random scenery, and `after' to alter rules for listing contents of
  1221. containers.
  1222.  
  1223.  
  1224.  
  1225. 5.3 Making new actions
  1226. ======================
  1227.  
  1228. The library's actions are easily added to.  For instance, add the
  1229. routine:
  1230.  
  1231.      [ BlorpleSub;
  1232.          "You speak the magic word ~Blorple~.  Nothing happens.";
  1233.      ];
  1234.  
  1235. (somewhere after the `Initialise' routine, say, to be tidy).  There is
  1236. now an action `Blorple' (though it doesn't do anything very
  1237. interesting).  One can use the command `<Blorple>;' to make it happen,
  1238. and could change the `before' routine of, say, the Corridor, to make
  1239. `Blorple' do something exciting in that one place.  In other words,
  1240. `Blorple' is now an action just like any other.
  1241.  
  1242. But the player can't yet type `blorple' and get this response, because
  1243. although the action exists, it hasn't been written into the grammar of
  1244. the game.  The grammar is a large table (mostly written out in the
  1245. `Grammar' library file).  It can easily be added to, and in this case
  1246. we simply add the lines
  1247.  
  1248.      Verb "blorple"
  1249.          *                               -> Blorple;
  1250.  
  1251. immediately after the inclusion of the `Grammar' file.  (The spacing is
  1252. just a matter of convention.)  This is about as simple as grammar lines
  1253. come, and means that only the word `blorple' can be used as a verb, and
  1254. it can't apply to any noun or nouns.  (Far more about grammar later.)
  1255.  
  1256. !!!! It is time to be more precise about the exact sequence of events.
  1257. Suppose the player is in the Bedquilt Room, and types `drop oyster'.
  1258. Once it has checked that this is a reasonable command, the normal rules
  1259. can be interrupted at eight different stages:
  1260.  
  1261.   1. Call `GamePreRoutine' (if there is one).  If this returns true,
  1262.      stop here.
  1263.  
  1264.   2. Call the `before' of the player.  If this returns true, stop here.
  1265.  
  1266.   3. Call the `before' of Bedquilt Room.  If this returns true, stop
  1267.      here.
  1268.  
  1269.   4. Then the `before' of the oyster.  If this returns true, stop here.
  1270.  
  1271.   5. Actually drop the object.
  1272.  
  1273.   6. Call the `after' of the player. If this returns true, stop here.
  1274.  
  1275.   7. Call the `after' of Bedquilt Room. If this returns true, stop here.
  1276.  
  1277.   8. Then the `after' of the oyster. If this returns true, stop here.
  1278.  
  1279.   9. Call `GamePostRoutine' (if there is one).  If this returns true,
  1280.      stop here.
  1281.  
  1282.  10. Print `Dropped.'
  1283.  
  1284. !!!!! `GamePreRoutine' and `GamePostRoutine' are examples of `entry
  1285. points', like `Initialise': routines you can provide to make global
  1286. rule changes.  Their use is a drastic measure to be avoided if
  1287. possible.  The player's own `before' and `after' will be discussed in
  1288. \S 11.
  1289.  
  1290. !!!!! `Fake actions' are just like real actions, except that they don't
  1291. occur in any game grammar, so they're never generated by the parser.
  1292. They're a neat way to pass `messages' from one object to another one.
  1293. Because they aren't defined implicitly in the grammar, they have to be
  1294. explicitly declared before use, by the directive:
  1295.  
  1296.      `Fake_Action' ACTION-NAME
  1297.  
  1298.  
  1299. 5.3.1 Exercise: medicine bottle
  1300. -------------------------------
  1301.  
  1302. !!!!! How can you make a medicine bottle, which can be opened in a
  1303. variety of ways in the game, so that the opening-code only occurs in the
  1304. bottle definition?
  1305.  
  1306. *Note Answer (medicine bottle)::.
  1307.  
  1308.  
  1309.  
  1310.  
  1311. 6 Containers, supporters and sub-objects
  1312. ****************************************
  1313.  
  1314.      The concept of a surface is implemented as a special kind of
  1315.      containment.  Objects which have surfaces on which other objects
  1316.      may sit are actually containers with an additional property of
  1317.      `surfaceness'.
  1318.  
  1319.      - P. David Lebling, `Zork and the Future'
  1320.  
  1321.  
  1322.  
  1323. 6.1 Introduction to containers
  1324. ==============================
  1325.  
  1326. Objects can be inside or on top of one another.  An object which has the
  1327. `container' attribute can contain things, like a box: one which has
  1328. `supporter' can hold them up, like a table.  (An object can't have both
  1329. at once.)  It can hold up to 100 items, by default: this is set by the
  1330. `capacity' property.
  1331.  
  1332. However, one can only put things inside a container when it has `open'.
  1333. If it has `openable', the player can open and close it at will.
  1334. (Unless it also has `locked'.)
  1335.  
  1336. To complicate matters, some containers are `transparent' (so that the
  1337. player can see inside them even when they are closed) and some are not.
  1338.  
  1339. Containers (and supporters) are able to react to things being put inside
  1340. them, or removed from them, by acting on the `Receive' and `LetGo'
  1341. actions.
  1342.  
  1343. !!!! `LetGo' and `Receive' are actually two of the fake actions: they
  1344. are the actions `Insert' and `Remove' looked at from the container's
  1345. point of view.
  1346.  
  1347.  
  1348. 6.1.1 Exercise: two boxes
  1349. -------------------------
  1350.  
  1351. Make a glass box and a steel box, which behave differently when the lamp
  1352. is shut up inside them.
  1353.  
  1354. *Note Answer (two boxes)::.
  1355.  
  1356.  
  1357. 6.1.2 Exercise: toothed bag
  1358. ---------------------------
  1359.  
  1360. Make the following, rather acquisitive bag:
  1361.  
  1362.      >put fish in bag
  1363.      The bag wriggles hideously as it swallows the fish.
  1364.      >get fish
  1365.      The bag defiantly bites itself shut on your hand until you desist.
  1366.  
  1367. *Note Answer (toothed bag)::.
  1368.  
  1369.  
  1370.  
  1371. 6.2 Containers which can be locked
  1372. ==================================
  1373.  
  1374. Objects which have `locked' cannot be opened, be they doors or
  1375. containers (or both).  But objects which have `lockable' can be locked
  1376. or unlocked with the appropriate key, which is declared in the
  1377. `with_key' property.  (If it is undeclared, then no key will fit.)
  1378.  
  1379. As a final example of a container, this is a fairly typical locked
  1380. cupboard:
  1381.  
  1382.      Nearby  cupboard "bolted cupboard"
  1383.       with   name "bolted" "cupboard",
  1384.              describe [;
  1385.                  if (self hasnt open)
  1386.                      "^A shut cupboard is bolted to one wall.";
  1387.                  "^Bolted up on one wall is an open cupboard.";
  1388.              ],
  1389.              with_key key
  1390.       has    locked container openable lockable static;
  1391.  
  1392.  
  1393.  
  1394. 6.3 Other uses for containers
  1395. =============================
  1396.  
  1397. Now suppose you want to make a portable television set which has four
  1398. different buttons on it.  Obviously when the television moves, its
  1399. buttons should move with it, and the sensible way to arrange this is to
  1400. make the four buttons possessions of the `television' object.
  1401.  
  1402. However, the television isn't a `container', and the player can't
  1403. normally `see' (that is, refer to) the possessions of an object.  So how
  1404. do we bring the buttons into the player's `view' without making them
  1405. removable, or allowing anyone to put extra things `into' the television?
  1406.  
  1407. This is what the `transparent' attribute is for: it is an extremely
  1408. useful device to allow the player to `see' (i.e., talk about) the
  1409. contents of an object.
  1410.  
  1411.  
  1412. 6.3.1 Exercise: television set
  1413. ------------------------------
  1414.  
  1415. Implement a television set with attached power button and screen.
  1416.  
  1417. *Note Answer (television set)::.
  1418.  
  1419.  
  1420.  
  1421.  
  1422. 7 Doors
  1423. *******
  1424.  
  1425.      Standing in front of you to the north, however, is a door
  1426.      surpassing anything you could have imagined. For starters, its
  1427.      massive lock is wrapped in a dozen six-inch thick iron chains. In
  1428.      addition, a certain five-headed monster...
  1429.  
  1430.      - Marc Blank and P. David Lebling, `Enchanter'
  1431.  
  1432.      O for doors to be open and an invite with gilded edges
  1433.      To dine with Lord Lobcock and Count Asthma.
  1434.      
  1435.      -- W. H. Auden (1907--1973), `Song'
  1436.  
  1437. A useful kind of object is a `door'.  This need not literally be a
  1438. door: it might be a rope-bridge or a ladder, for instance.  To set up a
  1439. `door':
  1440.  
  1441.   1. give the object the `door' attribute;
  1442.  
  1443.   2. set the `door_to' property to the destination;
  1444.  
  1445.   3. set the `door_dir' property to the direction which that would be,
  1446.      such as `n_to';
  1447.  
  1448.   4. make the room's map connection in that direction point to the door
  1449.      itself.
  1450.  
  1451. For example, here is a closed and locked door:
  1452.  
  1453.      Object  In_Immense_N_S_Passage "Immense N/S Passage"
  1454.       with   description "One end of an immense north/south passage.",
  1455.              s_to In_Giant_Room,
  1456.              n_to RustyDoor;
  1457.      Nearby  RustyDoor "rusty door"
  1458.       with   description "It's just a big iron door.",
  1459.              name "door" "hinge" "hinges" "massive" "rusty" "iron",
  1460.              when_closed "The way north is barred by a massive, rusty, \
  1461.                  iron door.",
  1462.              when_open "The way north leads through a massive, rusty, iron \
  1463.                  door.",
  1464.              door_to In_Cavern_With_Waterfall,
  1465.              door_dir n_to,
  1466.              with_key set_of_keys
  1467.       has    static door openable lockable locked;
  1468.  
  1469. (Note that the door is `static' - otherwise the player could pick it up
  1470. and walk away with it!)  The properties `when_closed' and `when_open'
  1471. give descriptions appropriate for the door in these two states.
  1472.  
  1473. Doors are rather one-way: they are only really present on one side.  If
  1474. a door needs to be accessible (openable and lockable from either side),
  1475. a neat trick is to make it present in both locations and to fix the
  1476. `door_to' and `door_dir' to the right way round for whichever side the
  1477. player is on.  Here, then, is a two-way door:
  1478.  
  1479.      Object  Grate "steel grate"
  1480.       with   name "grate" "lock" "gate" "grille" "metal" "strong" "steel"
  1481.                  "grating",
  1482.              description "It just looks like an ordinary grate mounted in \
  1483.                  concrete.",
  1484.              with_key set_of_keys,
  1485.              door_dir [;
  1486.                  if (location==Below_The_Grate) return u_to; return d_to;
  1487.              ],
  1488.              door_to [;
  1489.                  if (location==Below_The_Grate) return Outside_Grate;
  1490.                  return Below_The_Grate;
  1491.              ],
  1492.              describe [;
  1493.                  if (self has open) "^The grate stands open.";
  1494.                  if (self hasnt locked) "^The grate is unlocked but shut.";
  1495.                  rtrue;
  1496.              ],
  1497.              found_in  Below_The_Grate  Outside_Grate
  1498.       has    static door openable lockable locked;
  1499.  
  1500. where `Below_The_Grate' has `u_to' set to `Grate', and `Outside_Grate'
  1501. has `d_to' set to `Grate'.  The grate can now be opened, closed,
  1502. entered and locked from either above or below.
  1503.  
  1504. !!!! At first sight, it isn't obvious why doors have the `door_dir'
  1505.  
  1506. property.  Why does a door need to know which way it faces?  The idea is
  1507. that if there's an open door in the south wall, a player can go through
  1508. it either by typing `south' or `enter door'.  So what the `Enter'
  1509. action does (provided the door is actually open) is to cause the `Go'
  1510. action with the given direction.
  1511.  
  1512. !!!! This has one practical consequence: if you put `before' and
  1513. `after' routines on the `Enter' action for the `Grate', they only apply
  1514. to a player typing `enter grate' and not to one just typing `down'.
  1515. The way to trap both at once is to write a routine for the `d_to'
  1516. property of `Outside_Grate'.
  1517.  
  1518.  
  1519.  
  1520.  
  1521. 8 Switchable objects
  1522. ********************
  1523.  
  1524.      In one corner there is a machine which is reminiscent of a clothes
  1525.      dryer.  On its face is a switch which is labelled `START'. The
  1526.      switch does not appear to be manipulable by any human hand (unless
  1527.      the fingers are about 1/16 by 1/4 inch)...
  1528.  
  1529.      - `Zork'
  1530.  
  1531. Objects can also be `switchable'.  This means they can be turned off or
  1532. on, as if they had some kind of switch on them.  The object has the
  1533. attribute `on' if it's on.  For example:
  1534.  
  1535.      Object  searchlight "Gotham City searchlight" skyscraper
  1536.       with   name "search" "light" "template", article "the",
  1537.              description "It has some kind of template on it.",
  1538.              when_on "The old city searchlight shines out a bat against \
  1539.                  the feather-clouds of the darkening sky.",
  1540.              when_off "The old city searchlight, neglected but still \
  1541.                  functional, sits here."
  1542.       has    switchable static;
  1543.  
  1544. Here is a lamp which provides for batteries which will some day run
  1545. down, though the code to actually deplete these batteries (by
  1546. decrementing `time_left' every turn it's switched on) is omitted:
  1547.  
  1548.      Nearby  brass_lantern "brass lantern"
  1549.       with   name "lamp" "lantern" "shiny" "brass",
  1550.              when_off "There is a shiny brass lamp nearby.",
  1551.              when_on "Your lamp is here, gleaming brightly.",
  1552.              time_left 330,
  1553.              before [;
  1554.               Examine:
  1555.                  print "It is a shiny brass lamp";
  1556.                  if (brass_lantern hasnt on) ".  It is not currently lit.";
  1557.                  if (brass_lantern.time_left < 30) ", glowing dimly.";
  1558.                  ", glowing brightly.";
  1559.               Burn: <<SwitchOn brass_lantern>>;
  1560.               Rub: "Rubbing the electric lamp is not particularly \
  1561.                   rewarding.  Anyway, nothing exciting happens.";
  1562.               SwitchOn:
  1563.                  if (brass_lantern.time_left <= 0)
  1564.                      "Unfortunately, the batteries seem to be dead.";
  1565.              ],
  1566.              after [;
  1567.               SwitchOn: give brass_lantern light;
  1568.               SwitchOff: give brass_lantern ~light;
  1569.              ],
  1570.       has    switchable;
  1571.  
  1572.  
  1573.  
  1574.  
  1575. 9 Things to enter, travel in and push around
  1576. ********************************************
  1577.  
  1578.      ...the need to navigate a newly added river prompted the invention
  1579.      of vehicles (specifically, a boat).
  1580.  
  1581.      - P. David Lebling, Marc Blank and Timothy Anderson
  1582.  
  1583. Some objects in a game are `enterable', which means that a player can
  1584. get inside them.  The idea of `inside' here is that the player is only
  1585. half-in, as with a car or a psychiatrist's couch.  (If it's more like a
  1586. prison cell, then it should be a separate place.)  In practice one
  1587. often wants to make an `enterable' thing also a `container', or, as in
  1588. this example, a `supporter':
  1589.  
  1590.      Object  chair "dentist's chair" surgery
  1591.       with   name "dentists" "chair" "couch",
  1592.       has    enterable supporter;
  1593.  
  1594. All the classic games have vehicles (like boats, or fork lift trucks, or
  1595. hot air balloons) which the player can journey in, so Inform makes this
  1596. easy.  Here is a simple case:
  1597.  
  1598.      Object  car "little red car" cave
  1599.       with   name "little" "red" "car",
  1600.              description "Large enough to sit inside.  Among the controls \
  1601.                  is a prominent on/off switch.  The numberplate is KAR 1.",
  1602.              when_on "The red car sits here, its engine still running.",
  1603.              when_off "A little red car is parked here.",
  1604.              before [;
  1605.               Go:
  1606.                  if (car has on) "Brmm!  Brmm!";
  1607.                      print "(The ignition is off at the moment.)^";
  1608.              ],
  1609.       has    switchable enterable static container open;
  1610.  
  1611. Actually, this demonstrates a special rule.  If a player is inside an
  1612. `enterable' object and tries to move, say `north', the `before' routine
  1613. for the object is called with the action `Go', and `n_obj' as the noun.
  1614. If it returns false, the game disallows the attempt to move (as
  1615. usual).  If it returns true, then the vehicle and player move together
  1616. via the game's usual map.
  1617.  
  1618. !!!! Because you might want to drive the car `out' of a garage, the
  1619. `out' verb does not make the player get out of the car.  Usually the
  1620. player has to type something like `get out' to make this happen, though
  1621. of course the rules can be changed.
  1622.  
  1623. !!!! Objects like the car (if the hand brake is off) or, say, an
  1624. antiquated wireless on casters, are obviously too heavy to pick up but
  1625. the player should at least be able to push them from place to place.
  1626. When the player tries to do this, the `PushDir' action is generated.
  1627. Now, if the `before' routine returns false, the game will just say that
  1628. the player can't; and if it returns true, the game will do nothing at
  1629. all, guessing that the `before' routine has already printed something
  1630. more interesting.  So how does one actually tell Inform that the push
  1631. should be allowed?  The answer is that one has to do two things: call
  1632. the `AllowPushDir()' routine (a library routine), and then return true.
  1633. So, for example,
  1634.  
  1635.      Nearby  huge_ball "huge plaster-of-paris ball"
  1636.       with   name "huge" "plaster" "ball",
  1637.              description "A good eight feet across, though fairly \
  1638.                  lightweight.",
  1639.              initial "A huge plaster-of-paris ball rests here, eight feet \
  1640.                  wide.",
  1641.              before [;
  1642.               PushDir: AllowPushDir(); rtrue;
  1643.               Take, Remove: "There's a lot of plaster in an eight-foot \
  1644.                   sphere.";
  1645.              ],
  1646.              after [;
  1647.               PushDir: "The ball rattles about and is hard to stop once \
  1648.                   underway.";
  1649.              ],
  1650.       has    static;
  1651.  
  1652.  
  1653. 9.0.1 Exercise: the red car
  1654. ---------------------------
  1655.  
  1656. Alter the car so that it won't go up or down stairs.
  1657.  
  1658. *Note Answer (the red car)::.
  1659.  
  1660.  
  1661.  
  1662.  
  1663. 10 Living creatures and conversation
  1664. ************************************
  1665.  
  1666.      To know how to live is my trade and my art.
  1667.      
  1668.      -- Michel de Montaigne (1533--1592), `Essays'
  1669.  
  1670.      Everything that can be said can be said clearly.
  1671.      
  1672.      -- Ludwig Wittgenstein (1889--1951), `Tractatus'
  1673.  
  1674. This rummage through special kinds of objects finishes up with the most
  1675. sophisticated kind: living ones.  Animate objects (such as sea monsters,
  1676. mad aunts or nasty little dwarves) have a property called `life',
  1677. containing their rules.  This behaves just like a `before' or `after'
  1678. routine, but only the following actions apply:
  1679.  
  1680. `Attack'
  1681.      The player is making hostile advances...
  1682.  
  1683. `Kiss'
  1684.      ... or excessively friendly ones.
  1685.  
  1686. `ThrowAt'
  1687.      The player asked to throw `noun' at the creature.
  1688.  
  1689. `Give'
  1690.      The player asked to give `noun' to the creature...
  1691.  
  1692. `Show'
  1693.      ... or just to show it.
  1694.  
  1695. `Ask'
  1696.      The player asked the creature about something: `noun' holds the
  1697.      word.
  1698.  
  1699. `Answer'
  1700.      The player tried either of:
  1701.  
  1702.           `answer WORD to troll'
  1703.           `trool, SOMETHING NOT UNDERSTOOD'
  1704.  
  1705.      In either case the variable `special_word' is set to the dictionary
  1706.      entry of the first word, or 0 if it isn't in the dictionary, and
  1707.      `special_number' is set to an attempt to read it as a number.  (For
  1708.      instance, `computer, 143' will cause `special_number' to be set to
  1709.      143.)
  1710.  
  1711. `Order'
  1712.      On the other hand, an `Order' happens when the parser does
  1713.      understand what the player wants the creature to do: e.g., `troll,
  1714.      go south'.  `action', `noun' and `second' are set up as usual: in
  1715.      this case `action=##Go' and `noun=s_obj', while `second=0'.
  1716.  
  1717. If the routine doesn't exist, or returns false, events will take their
  1718. usual course.  Here is a full example:
  1719.  
  1720.      Object  snake "sullen snake" mists
  1721.       with   name "sullen" "snake",
  1722.              description "Perhaps a boa constrictor.  Perhaps not.",
  1723.              life [;
  1724.               Order:
  1725.                  if (action==##Go)
  1726.                      "The snake wasn't born yesterday.";
  1727.               Attack: "Lazily, the snake dodges your attack.";
  1728.               Kiss: "What a repulsive idea.";
  1729.               ThrowAt:
  1730.                  print "Effortlessly, the snake dodges ";
  1731.                  DefArt(inp1); ".";
  1732.               Answer, Show: "The snake disdains to comment.";
  1733.               Ask:
  1734.                  if (noun == 'mists')
  1735.                      "~Healthy and good for the skin, mists.~";
  1736.                  "~I'm only the obligatory monster.~";
  1737.               Give:
  1738.                  if (noun has edible) {
  1739.                      remove noun;
  1740.                      "~Mmm!  Thanks!  I still hate you, though.~";
  1741.                  }
  1742.                  "~Bleurghh!  Are you trying to poison me?~";
  1743.              ],
  1744.       has    animate;
  1745.  
  1746. Of course an `animate' still has `before' and `after' routines like any
  1747. other, so you can trap many other kinds of behaviour.  (The library
  1748. understands that, for example, an `animate' creature cannot be taken.)
  1749.  
  1750. !!!! `DefArt' is a routine which prints the short name of an object
  1751. along with its definite article, usually `the'.
  1752.  
  1753. Sometimes creatures should be `transparent', sometimes not.  Consider
  1754. these two cases of `animate' characters, for instance:
  1755.  
  1756.    * an urchin with something bulging inside his jacket pocket;
  1757.  
  1758.    * a hacker who has a bunch of keys hanging off his belt.
  1759.  
  1760. The hacker is `transparent', the urchin not.  That way the parser
  1761. prevents the player from referring to whatever the urchin is hiding
  1762. (even if the player has played the game before, and knows what is in
  1763. there and what it's called).  But the player can look at and be
  1764. tantalised by the hacker's keys.
  1765.  
  1766. !!!! Another way to trap some of these actions (those which do not
  1767. involve conversation, i.e., other than `Order', `Answer' or `Ask') is
  1768. to use `before' in the ordinary way.  This lets you change rules about,
  1769. say, giving things to people in particular places.  The `ThrowAt'
  1770. action is also an ordinary one (for coconut shies, greenhouse windows
  1771. and the like) but is given to `life' as well because most creatures
  1772. react to it, and it's a convenience to have all the rules for a
  1773. creature in one place.
  1774.  
  1775. !!!! A footnote about `Order': this is another `fake action'.  The
  1776. `before' and `after' routines of a room can't detect the player having
  1777. given a request to another character.  Also, if you want the snake to
  1778. obey when the player tells it to take something, you have to write the
  1779. code to do the actual taking yourself.  This isn't any problem in
  1780. practice.  (Try looking at the code for `Christopher' in the `Toyshop'
  1781. example game.)
  1782.  
  1783.  
  1784.  
  1785.  
  1786. 11 Starting, moving, changing and killing the player
  1787. ****************************************************
  1788.  
  1789.      There are only three events in a man's life; birth, life and death;
  1790.      he is not conscious of being born, he dies in pain and he forgets
  1791.      to live.
  1792.  
  1793.      - Jean de la Bruyère (1645-1696)
  1794.  
  1795.      That is the road we all have to take - over the Bridge of Sighs
  1796.      into eternity.
  1797.  
  1798.      - Søren Kierkegaard (1813-1855)
  1799.  
  1800. The player normally begins in the room which `location' is set to, and
  1801. setting `location' is the only absolute obligation on a game's
  1802. `Initialise' routine.  (The room may be initially dark if you so
  1803. choose, or rather if you provide no light source.)  In fact `location'
  1804. could be set to a chair or bed just as easily if the player is to start
  1805. seated or lying down.  If you would like to give the player some items
  1806. to begin with, `Initialise' should also `move' them to `player'.
  1807.  
  1808. To move the player about (for teleportation of some kind), two things
  1809. must be done: to move the player object, by
  1810.  
  1811.      move player to newroom;
  1812.  
  1813. and also to change the `location' variable, which says which room to
  1814. display on the status line:
  1815.  
  1816.      location = newroom;
  1817.  
  1818. The cleanest way to move the player is call `PlayerTo(place);' which
  1819. also sorts out things like only printing the new room's description if
  1820. there's enough light there to see by.
  1821.  
  1822. !!!! In general `location' can be different from `parent(player)' in
  1823. two ways: it can be `Darkness' (that is, the special object `thedark',
  1824. which behaves somewhat like a room), or it can be the actual room while
  1825. `parent(player)' is something the player sits inside, like (say) a jeep.
  1826.  
  1827. !!!! Calling `PlayerTo(place, 1);' will move the player without
  1828. printing anything, and in particular without printing any room
  1829. description.
  1830.  
  1831. The player's whole persona can easily be changed, by setting
  1832.  
  1833.      player.before = #r$MyNewRule;
  1834.  
  1835. where `MyNewRule' is a new `before' rule to be applied to every action
  1836. of the player's (or similarly for an `after' rule).  For instance, if a
  1837. cannon goes right next to the player, a period of deafness might ensue,
  1838. and this rule could stop the `Listen' action from taking its normal
  1839. course.
  1840.  
  1841. !!!! In fact a much more powerful trick is available: the `player' can
  1842. actually become a different character in the game, allowing the real
  1843. player at the keyboard to act through someone else.  Calling
  1844. `ChangePlayer(obj)' will transform the player to `obj'.  There's no
  1845. need for `obj' to have names like `me' or `myself'; the parser
  1846. understands these words automatically to refer to the
  1847. currently-inhabited `player' object.  However, it must provide a
  1848. `number' property (which the library will use for workspace).  The
  1849. maximum number of items the player can carry as that object will be its
  1850. `capacity'.  Finally, since `ChangePlayer' prints nothing, you may want
  1851. to conclude with a `<<Look>>;'
  1852.  
  1853. `ChangePlayer' has many possible applications.  The player who tampers
  1854. with Dr Frankenstein's brain transference machine may suddenly become
  1855. the Monster strapped to the table.  A player who drinks too much wine
  1856. could become a `drunk player object' to whom many different rules
  1857. apply.  The `snavig' spell of `Spellbreaker', which transforms the
  1858. player to an animal like the one cast upon, could be implemented thus.
  1859. More ambitiously, a game could have a stock of half a dozen main
  1860. characters, and the focus of play can switch between them.  A player
  1861. might have a team of four adventurers to explore a dungeon, and be able
  1862. to switch the one being controlled by typing the name.  (In this case,
  1863. an `AfterLife' routine - see below - may be needed to switch the focus
  1864. back to a still-living member of the team after one has met a sticky
  1865. end.)
  1866.  
  1867. !!!! Calling `ChangePlayer(object,1);' will do the same but make the
  1868. game print `(as Whoever)' during room descriptions.
  1869.  
  1870. The player is still alive for as long as the variable `deadflag' is
  1871. zero.  When set to 1, the player dies; when set to 2, the player wins;
  1872. and all higher values are taken as more exotic forms of death.  Now
  1873. Inform does not know what to call these exotica: so if they should
  1874. arise, it calls the `DeathMessage' routine, which is expected to look
  1875. at `deadflag' and can then print something like `You have changed'.
  1876.  
  1877. Many games allow reincarnation (or, as David M. Baggett points out, in
  1878. fact resurrection).  You too can allow this, by providing an
  1879. `AfterLife'.  This routine gets the chance to do as it pleases before
  1880. any `You are dead' type message appears, including resetting `deadflag'
  1881. back to 0 - which causes the game to proceed in the normal way, rather
  1882. than end.  `AfterLife' routines can be tricky to write, though, because
  1883. the game has to be set to a state which convincingly reflects what has
  1884. happened.  (For instance, try collapsing the bridge in `Advent' by
  1885. leading the bear across it, then being reincarnated and returning to
  1886. the scene.)
  1887.  
  1888.  
  1889. 11.0.1 Exercise: *wayhel*
  1890. -------------------------
  1891.  
  1892. !!!! In Central American legend, a sorceror can transform himself into a
  1893. *nagual*, a familiar such as a spider-monkey; indeed, each individual
  1894. has an animal self or *wayhel*, living in a volcanic land over which
  1895. the king, as a jaguar, rules.  Turn the player into his *wayhel*.
  1896.  
  1897. *Note Answer (wayhel)::.
  1898.  
  1899.  
  1900.  
  1901.  
  1902. 12 Printing out names of objects
  1903. ********************************
  1904.  
  1905.      And we were angry and poor and happy,
  1906.      And proud of seeing our names in print.
  1907.      
  1908.      -- G. K. Chesterton (1874-1936), `A Song of Defeat'
  1909.  
  1910. Inform has a special form of print command for this, `print object',
  1911. but *do not use it*.  Instead, call one of the following library
  1912. routines:
  1913.  
  1914. `DefArt(obj)'
  1915.      Print the object with its definite article
  1916.  
  1917. `CDefArt(obj)'
  1918.      The same, but capitalised
  1919.  
  1920. `InDefArt(obj)'
  1921.      Print the object with indefinite article
  1922.  
  1923. `PrintShortName(obj)'
  1924.      Print the object's short name alone
  1925.  
  1926. The indefinite article for an object is held in the property `article'
  1927. and is assumed to be `a' if none is declared.  That means that if the
  1928. short name starts with a vowel, you need to set it to `an'.  But
  1929. `article' offers much more amusement:
  1930.  
  1931.      a platinum bar, an orange balloon, your Aunt Jemima,
  1932.      some bundles of reeds, far too many marbles
  1933.  
  1934. are all examples of `article's.
  1935.  
  1936. Definite articles are always `the' unless an object is given the
  1937. attribute `proper', which makes it a proper noun and so not take a
  1938. definite article at all.  Thus
  1939.  
  1940.      the platinum bar, Aunt Jemima, Elbereth
  1941.  
  1942. are all printed by `DefArt', the latter two being `proper'.
  1943.  
  1944. As we shall later see (*note Naming of names::.), changing the short
  1945. name is easy.
  1946.  
  1947. !!!!! The reason `print object' is unsafe is that it prints the real,
  1948. `hardware and unchangeable' short name, whereas we want everything to
  1949. work nicely when the user changes the short name of an object in play:
  1950. so the library routines almost all indirect through `PrintShortName'
  1951. (except in two cases to do with `ChangePlayer', since the current
  1952. player's short name is always `yourself').
  1953.  
  1954.  
  1955. 12.0.1 Exercise: printing objects
  1956. ---------------------------------
  1957.  
  1958. !!!! Why does
  1959.  
  1960.      print CDefArt(obj), " falls to the floor.^";
  1961.  
  1962. seem to work, but mysteriously print the number 1 after the name of the
  1963. object?
  1964.  
  1965. *Note Answer (printing objects)::.
  1966.  
  1967.  
  1968.  
  1969.  
  1970. 13 Classes of objects
  1971. *********************
  1972.  
  1973. In most games there are groups of objects with certain rules in common.
  1974. As well as individual objects, Inform allows one to define classes in
  1975. almost exactly the same way.  The only difference between the layout of
  1976. a class and object definition is that a class has no short name or
  1977. initial location (since it does not correspond to a single real item).
  1978. For example:
  1979.  
  1980.      Class   Treasure
  1981.       with   depositpoints 10,
  1982.              after [;
  1983.               Take:
  1984.                  if (location==Inside_Building)
  1985.                      score=score-self.depositpoints;
  1986.                  score=score+5;
  1987.                  "Taken!";
  1988.               Drop:
  1989.                  score=score-5;
  1990.                  if (location==Inside_Building) {
  1991.                      score=score+self.depositpoints;
  1992.                      "Safely deposited.";
  1993.                  }
  1994.              ],
  1995.       has    valuable;
  1996.  
  1997. An object of this class inherits the properties and attributes it
  1998. defines: in this case, an object of class `Treasure' picks up the given
  1999. score and rules automatically.  So
  2000.  
  2001.      Nearby  bars_of_silver "bars of silver"
  2002.       class  Treasure
  2003.       with   description "They're probably worth a fortune!",
  2004.              initial "There are bars of silver here!",
  2005.              article "some",
  2006.              name "silver" "bars";
  2007.  
  2008. inherits the `depositpoints' value of 10 and the rules about taking and
  2009. dropping.  If the silver bars had themselves set `depositpoints' to 15,
  2010. say, then the value would be 15: i.e., the class would be over-ridden.
  2011.  
  2012. !!!! `depositpoints' isn't a library property: it's one defined in the
  2013. game this example is drawn from, the `Advent' example game.
  2014.  
  2015. We could also, for instance, have:
  2016.  
  2017.      Nearby  cake "valuable cake"
  2018.       class  Treasure
  2019.       with   description "Exquisite!",
  2020.              initial "There's a valuable cake here!",
  2021.              after [;
  2022.               Eat: "Your most expensive meal in ages, but worth it.";
  2023.              ],
  2024.              name "valuable" "cake"
  2025.       has    edible;
  2026.  
  2027. Now the cake has two `after' rules.  Both apply, but the rule in the
  2028. cake itself takes precedence, i.e., happens first.
  2029.  
  2030. !!!! An object can inherit from several classes at once.  Moreover, a
  2031. class can itself inherit from other classes, so one can easily make a
  2032. class for `like Treasure but with only 8 `depositpoints''.
  2033.  
  2034. !!!!! The `class' field of an object definition contains a list of
  2035. classes,
  2036.  
  2037.      `class' C1 ... Cn
  2038.  
  2039. in which case the object inherits first from C1, then from C2 and so on.
  2040. C2 over-rides C1 and so on along the line.  These classes may well
  2041. disagree with each other, so the order matters.  If C1 says
  2042. `depositpoints' is 5, C3 says it is 10 but the object definition itself
  2043. says 15 then the answer is 15.
  2044.  
  2045. !!!!! With some properties, the value is not replaced but added to: this
  2046. is what happened with `after' above.  These properties are those which
  2047. were declared as `additive', e.g., by
  2048.  
  2049.      Property additive before $ffff;
  2050.  
  2051. For instance, the standard Inform properties `name' and `before' are
  2052. both additive.  So we could add `name "treasure",' to the properties in
  2053. the class definition for `Treasure', and then all objects of that class
  2054. would respond to the word `treasure', as well as their own particular
  2055. names.
  2056.  
  2057.  
  2058.  
  2059.  
  2060. 14 Daemons and the passing of time
  2061. **********************************
  2062.  
  2063.      Some, such as Sleep and Love, were never human.  From this class an
  2064.      individual daemon is allotted to each human being as his `witness
  2065.      and guardian' through life.
  2066.  
  2067.      - C. S. Lewis (1898-1963), `The Discarded Image'
  2068.  
  2069.      Some daemon stole my pen (forgive th' offence)
  2070.      And once betrayed me into common sense.
  2071.      
  2072.      -- Alexander Pope (1688--1744), `The Dunciad'
  2073.  
  2074.  
  2075.  
  2076. 14.1 Daemons (routines that run each turn)
  2077. ==========================================
  2078.  
  2079. By tradition, a daemon is an event which happens each turn while it is
  2080. `active'.  The classic example is of a dwarf which appears in the cave:
  2081. it has a daemon routine attached for moving about, throwing knives at
  2082. the player and other pleasantries.
  2083.  
  2084. Each object can have a `daemon' of its own.  This is set going, and
  2085. stopped again, by calling the (library) routines
  2086.  
  2087.      StartDaemon(the-object);
  2088.      StopDaemon(the-object);
  2089.  
  2090. Once active, the `daemon' property of the object is called as a routine
  2091. each turn.  Daemons are often started by a game's `Initialise' routine,
  2092. and active throughout.
  2093.  
  2094. !!!! Be warned: this continues to happen even if the daemon is
  2095. associated with a room or item which has been left behind by the player.
  2096. Actually this is very useful, as it means daemons can be used for
  2097. `tidying-up operations', or for the consequences of the player's actions
  2098. to catch up with him.
  2099.  
  2100. Daemons often run a fair amount of code.  (There are plenty of good
  2101. examples in `Toyshop' and `Advent'.)  They shouldn't be ridiculously
  2102. slow if they will run more than once.  And some daemons so sit in the
  2103. background for enormously long times: for instance, the daemon in
  2104. `Advent' which hides until the player has managed to get all the
  2105. treasures, then pounces.  Such daemons ought to check their condition
  2106. and return as quickly as possible if it fails.
  2107.  
  2108.  
  2109. 14.1.1 Exercise: the thief
  2110. --------------------------
  2111.  
  2112. Many games contain `wandering monsters', characters who walk around the
  2113. map (usually hand-coded and not moving far abroad).  Use a daemon to
  2114. implement one who wanders as freely as the player, like the thief in
  2115. `Zork I'.
  2116.  
  2117. *Note Answer (the thief)::.
  2118.  
  2119.  
  2120. 14.1.2 Exercise: weights
  2121. ------------------------
  2122.  
  2123. Use a background daemon to implement a system of weights, so that the
  2124. player can only carry a certain weight before her strength gives out and
  2125. she is obliged to drop something.  It should allow for feathers to be
  2126. lighter than lawn-mowers.
  2127.  
  2128. *Note Answer (weights)::.
  2129.  
  2130.  
  2131.  
  2132. 14.2 Timers and fuses
  2133. =====================
  2134.  
  2135. A `timer' (these are traditionally called `fuses' but the author can
  2136. stand only so much tradition) can alternatively be attached to an
  2137. object.  (An object can't have both a `timer' and a `daemon' going at
  2138. the same time.)  A timer is started with
  2139.  
  2140.      StartTimer(the-object, time);
  2141.  
  2142. in which case it will `go off' (alarm clock-style) in the given number
  2143. of turns.  This means that its `time_out' property will be called (as a
  2144. routine), once and once only, when the time comes.
  2145.  
  2146. It can be deactivated (so that it will never go off) by calling
  2147.  
  2148.      StopTimer(the-object);
  2149.  
  2150. A timer is *required* to provide a `time_left' property, to hold the
  2151. amount of time left.  If it doesn't, the library will print an error
  2152. message at run-time.  You can alter `time_left' yourself, but setting
  2153. it to 0 does not stop the timer: use the routine `StopTimer' for that.
  2154.  
  2155. !!!! In early releases of the library, a `daemon' needed a `time_left'
  2156. as well, which was illogical and a nuisance: anyway, it's no longer the
  2157. case.
  2158.  
  2159. !!!! Normally, you can only have 32 timers or daemons active at the same
  2160. time as each other (there may be any number of inactive ones).  But this
  2161. limit is easily raised: just define the constant `MAX_TIMERS' to some
  2162. larger value, putting the definition in your code before the `Parser'
  2163. file is included.
  2164.  
  2165.  
  2166.  
  2167. 14.3 Routines that run when an object is in scope
  2168. =================================================
  2169.  
  2170. There is yet a third form of timed event.  If a room provides an
  2171. `each_turn' routine, then this will be called in each turn when the
  2172. player is in it; if an object provides `each_turn', this is called
  2173. whenever the object is nearby. For instance, a radio might blare out
  2174. music whenever it is nearby; a sword might glow whenever monsters are
  2175. nearby; or a stream running through several forest locations might
  2176. occasionally float objects by.
  2177.  
  2178. `Each turn' is entirely separate from daemons and timers.  Although an
  2179. object can't have both a timer and a daemon at the same time, it can
  2180. have an `each_turn' at the same time, and this is quite useful,
  2181. especially to run creatures.  An ogre with limited patience can
  2182. therefore have an `each_turn' routine which worries the player (`The
  2183. ogre stamps his feet angrily!', etc.)  while also having a timer set to
  2184. go off when his patience runs out.
  2185.  
  2186. !!!! `Nearby' actually means `in scope', a term which will be properly
  2187. explained later.  The idea is based on line of sight, which works well
  2188. in most cases.
  2189.  
  2190. !!!!! But it does mean that the radio will be inaudible when shut up
  2191. inside most containers - which is arguably fair enough - yet audible
  2192. when shut up inside transparent, say glass, ones.  You can always change
  2193. the scope rules using an `InScope' routine to get around this.  In case
  2194. you want to tell whether scope is being worked out for ordinary parsing
  2195. reasons or instead for `each_turn' processing, look at the `et_flag'
  2196. variable (0 in the former case, 1 in the latter).  Powerful effects are
  2197. available this way - you could put the radio in scope within all nearby
  2198. rooms so as to allow sound to travel.  Or you could make a thief
  2199. audible throughout the maze he is wandering around in, as in `Zork I'.
  2200.  
  2201. The library also has the (limited) ability to keep track of time of day
  2202. as the game goes on.
  2203.  
  2204. If you're writing a game with the time instead of the score and turns on
  2205. the status line, you can set the time by
  2206.  
  2207.      `SetTime(' 60 * HOURS + MINUTES`,' RATE `);'
  2208.  
  2209. The current time is held in the variable `the_time' and runs on a
  2210. 24-hour clock.  The RATE controls how rapidly time is moving: a RATE of
  2211. 0 means it is standing still (that is, that the library doesn't change
  2212. it: your routines still can).  A positive RATE means that that many
  2213. minutes pass between each turn; and negative RATE means that many turns
  2214. pass between each minute.
  2215.  
  2216. The time still won't appear on the game's status line unless you set
  2217.  
  2218.      Statusline time;
  2219.  
  2220. as a directive somewhere in your code.  And remember to start off the
  2221. clock by calling `SetTime' in your `Initialise' routine, if you're
  2222. going to use it.
  2223.  
  2224. !!!! Exactly what happens at the end of each turn is:
  2225.  
  2226.   1. The turns counter is incremented.
  2227.  
  2228.   2. The 24-clock is moved on.
  2229.  
  2230.   3. Daemons and timers are run (in no guaranteed order).
  2231.  
  2232.   4. `each_turn' takes place for the current room, and then for
  2233.      everything nearby (that is, in scope).
  2234.  
  2235.   5. The game's global `TimePasses()' routine is called.
  2236.  
  2237.   6. Light is re-considered (it may have changed as a result of events
  2238.      since this time last turn).
  2239.  
  2240. The sequence is abandoned if at any stage the player dies or wins.
  2241.  
  2242.  
  2243. 14.3.1 Exercise: passing midnight
  2244. ---------------------------------
  2245.  
  2246. How could you make your game take notice of the time passing midnight,
  2247. so that the day of the week could be nudged on?
  2248.  
  2249. *Note Answer (passing midnight)::.
  2250.  
  2251.  
  2252. 14.3.2 Exercise: suspended in mid-air
  2253. -------------------------------------
  2254.  
  2255. !!!! Suppose the player is magically suspended in mid-air, but that
  2256. anything let go of will fall out of sight.  The natural way to code this
  2257. is to use a daemon which gets rid of anything it finds on the floor
  2258. (this is better than just trapping `Drop' actions because objects might
  2259. end up on the floor in many different ways).  Why is using `each_turn'
  2260. better?
  2261.  
  2262. *Note Answer (suspended in mid-air)::.
  2263.  
  2264.  
  2265. 14.3.3 Exercise: varying rates of time
  2266. --------------------------------------
  2267.  
  2268. How would a game work if it involved a month-long archaeological dig,
  2269. where anything from days to minutes pass between successive game turns?
  2270.  
  2271. *Note Answer (varying rates of time)::.
  2272.  
  2273.  
  2274.  
  2275.  
  2276. 15 Adding verbs and grammar to the parser
  2277. *****************************************
  2278.  
  2279.      Grammar, which can govern even kings.
  2280.      
  2281.      -- Molière (1622--1673), `Les Femmes savantes'
  2282.  
  2283.      Language disguises thought ... The tacit conventions on which the
  2284.      understanding of everyday language depends are enormously
  2285.      complicated.
  2286.  
  2287.      - Ludwig Wittgenstein, `Tractatus'
  2288.  
  2289. The next few sections will delve deep into the parser.  Inform goes to a
  2290. great deal of trouble to make the parser as `open-access' as possible,
  2291. because a parser cannot ever be general enough for every game without
  2292. being extremely modifiable.  So there are very many ways to customise
  2293. the Inform parser, hopefully without the user needing to understand much
  2294. about how it works (because this is quite a long story).
  2295.  
  2296.  
  2297.  
  2298. 15.1 Adding grammar for new verbs
  2299. =================================
  2300.  
  2301. The first essential requirement of any parser is to accept the addition
  2302. of the grammar for a new verb.  In Inform code, grammar should appear at
  2303. the end of the source code for a game, and of course most of it is
  2304. written out in the `Grammar' header file, which all games using the
  2305. library include.  After this inclusion, you can add extras.
  2306.  
  2307. The directive for this is called `Verb', and here's a typical example:
  2308. some of the library's grammar for `take':
  2309.  
  2310.      Verb "take" "get" "pick" "lift"
  2311.          * "out"                         -> Exit
  2312.          * multi                         -> Take
  2313.          * multiinside "from" noun       -> Remove
  2314.          * "in" noun                     -> Enter
  2315.          * multiinside "off" noun        -> Remove
  2316.          * "off" held                    -> Disrobe
  2317.          * "inventory"                   -> Inv;
  2318.  
  2319. This declares a verb, for which `take', `get' and so on are synonyms,
  2320. and which can take seven different courses.
  2321.  
  2322. !!!! It should be noted that these really are synonyms: the parser
  2323. thinks `take' and `get' are exactly the same.  Sometimes this has odd
  2324. results, so that although `get in bed' is correctly understood as a
  2325. request to enter the bed, `take in washing' is misunderstood as a
  2326. request to enter the washing.  You could either get around this by
  2327. writing separate grammars for the two nearly-synonyms, or can cheat and
  2328. see if the variable `verb_word=='take'' or `'get''.  Mostly, though,
  2329. you don't mind if a few odd things are accepted by the parser: what
  2330. matters more is that sensible things are not rejected by it.
  2331.  
  2332. When it ploughs through what the player has typed, the parser tries to
  2333. match each line in turn, starting at the top.  The first line will only
  2334. be matched if the player has typed something like `get out'.  The
  2335. second line is more interesting: it allows the player to type a single
  2336. object or a list of objects.  So the second line could be matched by
  2337.  
  2338.      `take the banana'
  2339.      `get all the fruit except the apple'
  2340.  
  2341. There need be no grammar at all after the verb: for example, a grammar
  2342. for `inventory' could be as simple as
  2343.  
  2344.      Verb "invent" "inv" "i"
  2345.          *                               -> Inv;
  2346.  
  2347. After the `->' in each line is the name of an action.  This is how
  2348. actions are defined: they are the names which appear in grammar lines
  2349. like this one.  Remember that if you do create an action this way, you
  2350. also have to write a routine to execute the action, even if it's one
  2351. which doesn't do very much.  For instance:
  2352.  
  2353.      [ XyzzySub; "Nothing happens."; ];
  2354.      Verb "xyzzy"
  2355.          *                               -> Xyzzy;
  2356.  
  2357. will make a new magic-word verb `xyzzy', which always says `Nothing
  2358. happens' - always, that is, unless some `before' rule gets there first,
  2359. as it might do in certain magic places.  (The name of the routine is
  2360. always the name of the action with `Sub' appended.)
  2361.  
  2362. The new action `Xyzzy' is treated exactly like all the standard Inform
  2363. actions: `##Xyzzy' gives its action number, and you can write `before'
  2364. and `after' rules for it in `Xyzzy:' fields just as you would for, say,
  2365. `Take'.
  2366.  
  2367.  
  2368.  
  2369. 15.2 Grammar tokens
  2370. ===================
  2371.  
  2372. The individual words in the grammar (after the `*' and before the `->')
  2373. are called `tokens'.  In increasing order of complexity, this is the
  2374. complete list:
  2375.  
  2376. `"WORD"'
  2377.      that literal word only
  2378.  
  2379. `noun'
  2380.      any object in scope
  2381.  
  2382. `held'
  2383.      object held by the player
  2384.  
  2385. `creature'
  2386.      an object in scope which is `animate'
  2387.  
  2388. `multi'
  2389.      one or more objects in scope
  2390.  
  2391. `multiheld'
  2392.      one or more held objects
  2393.  
  2394. `multiexcept'
  2395.      one or more in scope, except the other
  2396.  
  2397. `multiinside'
  2398.      one or more in scope, inside the other
  2399.  
  2400. `ATTRIBUTE'
  2401.      any object in scope which has the attribute
  2402.  
  2403. `noun = ROUTINE'
  2404.      any object in scope passing the given test
  2405.  
  2406. `scope = ROUTINE'
  2407.      an object in this definition of scope
  2408.  
  2409. `special'
  2410.      *any* single word or number
  2411.  
  2412. `number'
  2413.      a number only
  2414.  
  2415. `ROUTINE'
  2416.      any text accepted by the given routine
  2417.  
  2418. In the case of `noun = 'ROUTINE, the parser applies the following test:
  2419. the variable `noun' is set to the object in question, and the routine
  2420. is called.  If it returns true, the parser accepts the object, and
  2421. otherwise it rejects it.
  2422.  
  2423. `number' matches any decimal number from 0 upwards (though it rounds
  2424. off large numbers to 10000), and also matches the numbers `one' to
  2425. `twenty' written in English.
  2426.  
  2427. The token `special' is now obselete.
  2428.  
  2429. For now, we shall take `in scope' to mean `visible to the player'.  It
  2430. is quite important in some cases to know exactly what this means, so a
  2431. better definition will be given later.
  2432.  
  2433. The `held' token is convenient for two reasons.  Firstly, many actions
  2434. only sensibly apply to things being held (such as `Eat' or `Wear'), and
  2435. using this token in the grammar you can make sure that the action is
  2436. never generated by the parser unless the object is being held.  That
  2437. saves on always having to write `You can't eat what you're not holding'
  2438. code.  Secondly, suppose we have grammar
  2439.  
  2440.      Verb "eat"
  2441.          * held                          -> Eat;
  2442.  
  2443. and the player types
  2444.  
  2445.      `eat the banana'
  2446.  
  2447. while the banana is plainly in view, on a shelf, say.  It would be
  2448. rather petty of the game to refuse on the grounds that the banana is not
  2449. being held.  So the parser will generate a `Take' action for the banana
  2450. and then, if the `Take' action succeeds, an `Eat' action.  (Notice that
  2451. the parser does not just pick up the object, but issues an action in
  2452. the proper way - so if the banana had rules making it too slippery to
  2453. pick up, it won't be picked up.)
  2454.  
  2455. The `multi-' tokens indicate that a list of one or more objects can go
  2456. here.  (The parser works out all the things the player has asked for,
  2457. sorting out plural nouns and words like `except' by itself, and then
  2458. generates actions for each one.)  `multiexcept' is provided to make
  2459. commands like
  2460.  
  2461.      `put everything in the rucksack'
  2462.  
  2463. parsable: the `everything' is matched by all of the player's possessions
  2464. except the rucksack (this stops the parser from generating an action to
  2465. put the rucksack inside itself).  Similarly `multiinside' handles:
  2466.  
  2467.      `remove everything from the cupboard'
  2468.  
  2469. A restriction here is that a single grammar line can only contain one
  2470. `multi-' token: so `hit everything with everything' can't be parsed
  2471. (straightforwardly: you can parse anything with a little more effort).
  2472. On the whole, this is no bad thing.
  2473.  
  2474. The reason not all nouns can be multiple in the first place is that too
  2475. helpful a parser makes too easy a game.  You probably don't want to
  2476. allow something like
  2477.  
  2478.      `unlock the mystery door with all the keys'
  2479.  
  2480. - you want the player to suffer having to try them one at a time, or
  2481. else to be thinking.  (Of course if you do want to allow this it is easy
  2482. enough to change the grammar: the point is that you have the option.)
  2483.  
  2484. We can also sort out objects according to attributes that they have:
  2485.  
  2486.      Verb "use" "employ" "utilise"
  2487.          * edible                        -> Eat
  2488.          * clothing                      -> Wear
  2489.            ... and so on ...
  2490.          * enterable                     -> Enter;
  2491.  
  2492. and this is how attributes are used as tokens.  (The library grammar
  2493. does not contain such an appallingly convenient verb!)
  2494.  
  2495. Since you can define your own attributes, it is therefore easy to make a
  2496. grammar line which matches only your own class of object.
  2497.  
  2498. !!!! A footnote: the `creature' token is thus equivalent to writing
  2499. `animate'; but it dates back to the earliest days of Inform, and does
  2500. no harm.
  2501.  
  2502. Sometimes even that isn't flexible enough.  Here is a verb, `free',
  2503. which should only apply to animal kept in a cage:
  2504.  
  2505.      [ CagedCreature;
  2506.          if (noun in wicker_cage) rtrue; rfalse;
  2507.      ];
  2508.      Verb "free" "release"
  2509.          * noun=CagedCreature            -> FreeAnimal;
  2510.  
  2511. So that only nouns which pass the `CagedCreature' test are allowed.
  2512. (The `CagedCreature' routine can appear anywhere in the code, though
  2513. it's tidier to keep it nearby.)
  2514.  
  2515.  
  2516.  
  2517. 15.3 Parsing numbers
  2518. ====================
  2519.  
  2520. So far, all the tokens were to tell the parser which of the objects in
  2521. scope were acceptable.  Exactly what `in scope' means will be gone into
  2522. later, and so will the powerful `scope='... token.  Here we next want
  2523. the parser to match things other than names of objects and prepositions
  2524. like `into'.  The simplest useful case is of numbers, for example:
  2525.  
  2526.      Verb "type"
  2527.          * number                        -> TypeNum;
  2528.  
  2529. so that the TypeNum action will happen if the player types `type 504' or
  2530. `type seventeen'.
  2531.  
  2532. !!!! In fact, you're allowed to provide your own number-parsing routine,
  2533. so many sneaky possibilities are open here - Roman numerals,
  2534. coordinates like `J4', long telephone numbers (which would be too large
  2535. to fit into integer variables in Inform), understanding English numbers
  2536. and so on.  This takes the form
  2537.  
  2538.      [ ParseNumber buffer length;
  2539.          ! returning 0 if no match is made, or the number otherwise
  2540.      ];
  2541.  
  2542. and examines the supposed `number' held at the byte address `buffer',
  2543. which is a row of ASCII characters of the given `length'.  If you
  2544. declare a `ParseNumber' routine, then the parser will always try this
  2545. first when trying to decode something as a number (and if it fails will
  2546. fall back on its own number-parsing routine).
  2547.  
  2548. !!!!! For not-very-good internal reasons, `ParseNumber' can't return 0
  2549. to mean the number zero.  Probably `zero' won't be needed too often,
  2550. but if it is you can always return some value like 1000 and code the
  2551. verb in question to understand this as 0.
  2552.  
  2553. !!!!! You can give a routine to parse anything:
  2554.  
  2555.      [ French w n; w=NextWord();
  2556.          if (w=='un' or 'une') n=1;
  2557.          if (w=='deux')        n=2;
  2558.          if (w=='trois')       n=3;
  2559.          if (w=='quatre')      n=4;
  2560.          if (w=='cinq')        n=5;
  2561.          if (n==0) return -1;
  2562.          parsed_number = n; return 1;
  2563.      ];
  2564.  
  2565. will detect low numbers in French, and could be used by something like:
  2566.  
  2567.      Verb "type"
  2568.          * French                        -> TypeFrenchNum
  2569.          * number                        -> TypeNum;
  2570.  
  2571. The specification for such a routine is as follows: it is to use
  2572. `NextWord' (possibly several times) to look at the appropriate words
  2573. which the user has typed.  The variable `wn' (current word number) may
  2574. also be helpful.  The routine must return
  2575.  
  2576. `-1'
  2577.      if the user's input isn't understood,
  2578.  
  2579. `1'
  2580.      if there is a numerical value resulting, or
  2581.  
  2582. `n'
  2583.      if object number n is understood.
  2584.  
  2585. In the case of a number, the actual value should be put into the
  2586. variable `parsed_number'. On an unsuccessful match (returning -1) it
  2587. doesn't matter what the final value of `wn' is.  On a successful one it
  2588. should be left pointing to the next thing *after* what the routine
  2589. understood.  (Since `NextWord' moves `wn' on by one each time it is
  2590. called, this happens automatically unless the routine has read too far.)
  2591.  
  2592.  
  2593. 15.3.1 Exercise: footnotes
  2594. --------------------------
  2595.  
  2596. (A beautiful feature stolen from David M. Baggett's game `The Legend
  2597. Lives', which uses it to great effect.)  Some games produce footnotes
  2598. every now and then.  Arrange matters so that these are numbered `[1]',
  2599. `[2]' and so on in order of appearance, to be read by the player when
  2600. `footnote 1' is typed.
  2601.  
  2602. *Note Answer (footnotes)::.
  2603.  
  2604.  
  2605.  
  2606. 15.4 Extending the library grammar
  2607. ==================================
  2608.  
  2609. That's all about tokens: back to verb definition commands, because some
  2610. of the above examples are slightly contrived - they create wholly new
  2611. and unlikely verbs.  More often, one would want, say, a big array of
  2612. labelled buttons, any of which could be pushed.  So the verb for `push'
  2613. ought to be extended, and for this the `Extend' directive is provided:
  2614.  
  2615.      Extend "push"
  2616.          * Button                        -> PushButton;
  2617.  
  2618. A routine called `Button' could then be written to accept things like
  2619.  
  2620.      `button j16', `d11', `a5 button'.
  2621.  
  2622. The point of `Extend' is that it is against the spirit of the library
  2623. to alter the standard library files - including the grammar table -
  2624. unless absolutely necessary.
  2625.  
  2626. !!!!! Actually, there's a better way to provide these buttons, so that
  2627. they work with any verb automatically, and that's to make a button
  2628. object with a `parse_name' routine which cunningly extracts the button
  2629. number as it parses: see the game `Balances' for an example of this.
  2630.  
  2631. Normally, extra lines of grammar are added at the bottom of those
  2632. already there.  This may not be what you want.  For instance, `take' has
  2633. a grammar line
  2634.  
  2635.          * multi                         -> Take
  2636.  
  2637. quite early on.  So if you want to add a grammar line which diverts
  2638. `take something-edible' to a different action, like so:
  2639.  
  2640.          * edible                        -> Eat
  2641.  
  2642. then it's no good adding this at the bottom of the `Take' grammar,
  2643. because the earlier line will always be matched first.  Thus, you really
  2644. want to insert your line at the top, not the bottom, in this case.  The
  2645. right command is
  2646.  
  2647.      Extend "take" first
  2648.          * edible                        -> Eat;
  2649.  
  2650. You might even want to actually replace the old grammar completely, not
  2651. just add a line or two.  For this, use
  2652.  
  2653.      Extend "push" replace
  2654.          * Button                        -> PushButton;
  2655.  
  2656. and now `push' can be used only in this way.  To sum up, `Extend' can
  2657. take three keywords:
  2658.  
  2659. `replace'
  2660.      completely replace the old grammar with this one
  2661.  
  2662. `first'
  2663.      insert the new grammar at the top of the old one
  2664.  
  2665. `last'
  2666.      insert the new grammar at the bottom of the old one
  2667.  
  2668. with `last' being the default (which doesn't need to be said
  2669. explicitly).
  2670.  
  2671.  
  2672.  
  2673. 15.5 Meta verbs and unknown verbs
  2674. =================================
  2675.  
  2676. !!!! Another convenience is to define `meta' verbs - verbs which are
  2677. not really part of the game, such as `save', `score' and `quit'.  (You
  2678. probably want to add your own debugging commands as meta-verbs: if you
  2679. make them ordinary verbs, then they may work most of the time, but
  2680. might be interfered with by game rules, and will take up `game time'.)
  2681. To declare a verb as `meta', just add the word after the command.  For
  2682. instance, the library defines
  2683.  
  2684.      Verb meta "score"
  2685.          *                               -> Score;
  2686.  
  2687. The parser will match the grammar exactly in the normal way, but treats
  2688. the resulting action as outside the game - taking no time up, and
  2689. possible at any moment.
  2690.  
  2691. !!!!! There are (a few) times when verb definition commands are not
  2692. enough.  For example, in the original `Advent' (or `Colossal Cave'),
  2693. the player could type the name of a not-too-distant place which had
  2694. previously been visited, and be taken there.  There are several ways to
  2695. code this - say, with 60 rather similar verb definitions, or with a
  2696. single `travel' verb which has 60 synonyms, whose action routine looks
  2697. at the parser's `verb_word' variable to see which one was typed - but
  2698. here's another.  The library will call the `UnknownVerb' routine (if
  2699. you provide one) when the parser can't even get past the first word.
  2700. This has two options: it can return false, in which case the parser
  2701. just goes on to complain as it would have done anyway.  Otherwise, it
  2702. can return a verb word which is substituted for what the player
  2703. actually typed.  Here is a foolish example:
  2704.  
  2705.      [ UnknownVerb w;
  2706.          if (w=='shazam') {
  2707.              print "Shazam!^";
  2708.              return 'inventory';
  2709.          }
  2710.          rfalse;
  2711.      ];
  2712.  
  2713. which responds to the magic word `shazam' by printing `Shazam!' and
  2714. then, rather disappointingly, taking the player's inventory.  But in the
  2715. example above, it could be used to look for the word `w' through the
  2716. locations of the game, store the place away in some global variable,
  2717. and then return `'go''.  The `GoSub' routine could then be fixed to
  2718. look at this variable.
  2719.  
  2720. !!!!! If you allow a flexible collection of verbs (say, names of spells
  2721. or places) then you may want a single `dummy' verb to stand for
  2722. whichever is being typed.  This may make the parser produce strange
  2723. questions because it is unable to sensibly print the verb back at the
  2724. player, but you can fix this using the `PrintVerb' entry point (*note
  2725. Library entry points::.).  See the exercise below.
  2726.  
  2727.  
  2728. 15.5.1 Exercise: unknown verbs
  2729. ------------------------------
  2730.  
  2731. !!!!! Why is it usually a bad idea to print text out in an `UnknownVerb'
  2732. routine?
  2733.  
  2734. *Note Answer (unknown verbs)::.
  2735.  
  2736.  
  2737. 15.5.2 Exercise: control panel
  2738. ------------------------------
  2739.  
  2740. !!!! A tricky one: code a spaceship whose control panel has five sliding
  2741. controls, each of which can be set to a numerical value, so that the
  2742. game looks like:
  2743.  
  2744.      >look
  2745.      Machine Room
  2746.      There is a control panel here, with five slides, each of which can
  2747.      be set to a numerical value.
  2748.      
  2749.      >push slide one to 5
  2750.      You set slide number 1 to the value 5.
  2751.      
  2752.      >examine the first slide
  2753.      Slide number 1 currently stands at 5.
  2754.      
  2755.      >set four to six
  2756.      You set slide number 4 to the value 6.
  2757.  
  2758. *Note Answer (control panel)::.
  2759.  
  2760.  
  2761. 15.5.3 Exercise: quoted strings
  2762. -------------------------------
  2763.  
  2764. !!!!! An even trickier one: write a parsing routine which will accept
  2765. any amount of text (including spaces, full stops and commas) between
  2766. double-quotes as a single token.
  2767.  
  2768. *Note Answer (quoted strings)::.
  2769.  
  2770.  
  2771. 15.5.4 Exercise: named rooms
  2772. ----------------------------
  2773.  
  2774. !!!!! And another: implement the Crowther and Woods feature of moving
  2775. from one room to another by typing its name, discussed above, using a
  2776. dummy verb and without using `Replace' to change any library routines.
  2777.  
  2778. *Note Answer (named rooms)::.
  2779.  
  2780.  
  2781.  
  2782.  
  2783. 16 Scope and what you can see
  2784. *****************************
  2785.  
  2786.      He cannot see beyond his own nose.  Even the fingers he
  2787.      outstretches from it to the world are (as I shall suggest) often
  2788.      invisible to him.
  2789.  
  2790.      - Max Beerbohm (1872-1956), of George Bernard Shaw
  2791.  
  2792.      Wherefore are these things hid?
  2793.      
  2794.      -- William Shakespeare (1564--1616), `Twelfth Night'
  2795.  
  2796.  
  2797.  
  2798. 16.1 What `in scope' means
  2799. ==========================
  2800.  
  2801. Time to say what `in scope' means.  This definition is one of the most
  2802. important algorithms in the game, although it is buried inside the
  2803. parser, because it decides what the player is allowed to refer to: so
  2804. here it is in full.  The following are in scope:
  2805.  
  2806.      the player's immediate possessions;
  2807.      the 12 compass directions;
  2808.      *if* there is light, the objects in the same place as the player.
  2809.  
  2810. In addition, if an object is in scope then its immediate possessions are
  2811. in scope, *if* it is `see-through', which means that:
  2812.  
  2813.      the object has `supporter', *or*
  2814.      the object has `transparent', *or*
  2815.      the object is an `open' `container'.
  2816.  
  2817. The definition of when there is light will be gone into in the next
  2818. section.
  2819.  
  2820. !!!! Many things are still in scope in a dark room - so the player can
  2821. still turn a lamp on if it's being carried.  On the other hand, a
  2822. player who puts the lamp on the ground and turns it off then loses the
  2823. ability to turn it back on again, because it is out of scope.  (This
  2824. can be changed; *Note Changing scope::.)
  2825.  
  2826. !!!! The compass direction objects make sense as objects.  The player
  2827. can always type something like
  2828.  
  2829.      `attack the south wall'
  2830.  
  2831. (and a `before' rule for the room in question could make something
  2832. unusual happen as a result).  The compass directions are visible in the
  2833. dark, as otherwise the player could not still walk around.
  2834.  
  2835. !!!! The parser applies scope rules to other people too, not just the
  2836. player.  Thus `dwarf, drop sword' will be accepted even if the sword is
  2837. invisible to the player provided it is visible to the dwarf.
  2838.  
  2839. !!!! Items with the `concealed' attribute may be concealed from
  2840. ordinary descriptions - but the parser still sees them: they are still
  2841. in scope.  (If you want things to be both concealed and unreferrable-to,
  2842. put them somewhere else!)
  2843.  
  2844. !!!!! Actually, the above definition is not quite right, because the
  2845. compass directions are not in scope when the player asks for a plural
  2846. number of things, like `take all the knives'.  (This makes some of the
  2847. parser's plural algorithms run faster.)  Also, for a `multiexcept'
  2848. token, the other object is not in scope; and for a `multiinside' token,
  2849. only objects in the other object are in scope.  This makes `take
  2850. everything from the cupboard' work in the natural way.
  2851.  
  2852.  
  2853.  
  2854. 16.2 Changing the scope rules
  2855. =============================
  2856.  
  2857. The rest of this section is about how to change the scope rules.  As
  2858. usual with Inform, you can change them globally, but it's more efficient
  2859. and safer to do so only locally.
  2860.  
  2861. A typical example: how do we allow the player to ask questions like the
  2862. traditional `what is a grue'?  The `grue' part ought to be parsed as if
  2863. it were a noun, so that we could distinguish between, say, a `garden
  2864. grue' and a `wild grue'.  So it isn't good enough to look only at a
  2865. single word.  Here is one solution:
  2866.  
  2867.      Object questions "qs";
  2868.      [ QuerySub;
  2869.          print_paddr noun.description; new_line;
  2870.      ];
  2871.      [ Topic i;
  2872.          if (scope_stage==1) rfalse;
  2873.          if (scope_stage==2) {
  2874.              objectloop (i in questions) PlaceInScope(i);
  2875.              rtrue;
  2876.          }
  2877.          "At the moment, even the simplest questions confuse you.";
  2878.      ];
  2879.  
  2880. where the actual questions are themselves objects which belong to the
  2881. `questions' object, like so:
  2882.  
  2883.      Object  q1 "long count" questions
  2884.       with   name "long" "count",
  2885.              description "The Long Count is the great Mayan cycle of time, \
  2886.                  which began in 3114 BC and will finish with the world's \
  2887.                  end in 2012 AD.";
  2888.  
  2889. and we also have a grammar line:
  2890.  
  2891.      Verb "what"
  2892.          * "is"  scope=Topic              -> Query
  2893.          * "was" scope=Topic              -> Query;
  2894.  
  2895. (Note that the `questions' and `q1' objects are out of the game for
  2896. every other purpose.  The name `qs' doesn't matter; the individual
  2897. questions are named so that the parser might be able to say `Which do
  2898. you mean, the long count or the short count?' if the player just asked
  2899. `what is the count'.)  Here's what happens: when the parser reaches
  2900. `scope=Topic', it calls the `Topic' routine with the variable
  2901. `scope_stage' set to 1.  The routine should return 1 (true) if it is
  2902. prepared to allow multiple objects to be accepted here, and 0 (false)
  2903. otherwise: as we don't want `what is everything' to list all the
  2904. questions and answers in the game, we return false.
  2905.  
  2906. A little later on in its machinations, the parser again calls `Topic'
  2907. with `scope_stage' now set to 2.  `Topic' is now under an obligation to
  2908. tell the parser which objects are to be in scope.  It can call two
  2909. parser routines to do this.
  2910.  
  2911.      ScopeWithin(object)
  2912.  
  2913. puts everything inside the object into scope, though not the object
  2914. itself;
  2915.  
  2916.      PlaceInScope(object)
  2917.  
  2918. puts just a single object into scope.  It is perfectly legal to declare
  2919. something in scope that `would have been in scope anyway': or even
  2920. something which is in a different room altogether from the actor
  2921. concerned, say at the other end of a telephone line.  Our scope routine
  2922. `Topic' should then return
  2923.  
  2924. `0 (false)'
  2925.      to carry on with the usual scope rules, so that everything that
  2926.      would usually be in scope still is, and
  2927.  
  2928. `1 (true)'
  2929.      to tell the parser not to put any more objects into scope.
  2930.  
  2931. (So at `scope_stage' 2 it is quite permissible to do nothing but return
  2932. false, whereupon the usual rules apply.)  `Topic' returns true because
  2933. it wants only question topics to be in scope, not question topics
  2934. together with everything near the player.
  2935.  
  2936. If the player had typed `what is the long count', that would be all
  2937. that happens and all would be well.  On the other hand, if the player
  2938. typed `what is the lgon cnout' owing to a bout of dyslexia, the error
  2939. message which the parser would usually produce (`You can't see any such
  2940. thing') would be unsatisfactory.  So if parsing failed at this token,
  2941. then `Topic' is called at `scope_stage' 3 to print out a suitable error
  2942. message.  (It must provide one.)
  2943.  
  2944. !!!! The `scope=' notation is available only under Inform 5.4 and later.
  2945.  
  2946. !!!! Note that `ScopeWithin(object)' extends the scope down through its
  2947. possessions according to the usual rules (i.e., depending on their
  2948. transparency, whether they're containers and so in).  The definition of
  2949. `Topic' above shows how to put just the direct possessions into scope.
  2950.  
  2951.  
  2952. 16.2.1 Exercise: purloin verb
  2953. -----------------------------
  2954.  
  2955. Write a token which puts everything in scope, so that you could have a
  2956. debugging `purloin' verb which could take anything (regardless of where
  2957. it was and the rules applying to it).
  2958.  
  2959. *Note Answer (purloin verb)::.
  2960.  
  2961.  
  2962.  
  2963. 16.3 Changing the global scope rules
  2964. ====================================
  2965.  
  2966. Changing the global definition of scope should be done cautiously (there
  2967. may be unanticipated side effects); bear in mind that scope decisions
  2968. need to be taken often - every time an object token is parsed, so
  2969. perhaps five to ten times in every game turn - and hence moderately
  2970. quickly.
  2971.  
  2972. To do this one provides a routine called
  2973.  
  2974.      InScope(actor)
  2975.  
  2976. where the `actor' is the person whom the parser is working out scope
  2977. for; usually, then, `actor=player', but this should not be assumed to
  2978. be always the case.  If the routine decides that a particular object
  2979. should be in scope for the actor, it should execute `InScope' and
  2980. `ScopeWithin' just as above, and return true or false (as if it were at
  2981. `scope_stage' 2).  Thus, it is vital to return false in circumstances
  2982. when you don't want to intervene.
  2983.  
  2984. !!!! In the case of a token `scope='ROUTINE, the ROUTINE gets first
  2985. crack at scope-changing, and `InScope' will only be reached if it
  2986. returns false to signify `carry on'.
  2987.  
  2988. Here are some examples.  Firstly, as promised above, how to change the
  2989. rule that `things you've just dropped disappear in the dark':
  2990.  
  2991.      [ InScope person i;
  2992.          if (person==player && location==thedark)
  2993.              objectloop (i near player)
  2994.                  if (i has moved)
  2995.                      PlaceInScope(i);
  2996.          rfalse;
  2997.      ];
  2998.  
  2999. With this routine added, the objects in the dark room the player is in
  3000. are in scope only if they have `moved' (that is, have been held by the
  3001. player in the past); and even then, are in scope only to the player.
  3002.  
  3003. !!!! By combining an `InScope' routine with token-parsing routines in
  3004. grammar, dramatic effects are possible.  See the example game
  3005. `Balances', for instance.
  3006.  
  3007.  
  3008. 16.3.1 Exercise: light switch
  3009. -----------------------------
  3010.  
  3011. !!!!! Code the following puzzle, which has nasty scope complications.
  3012. In an initially dark room there is a light switch.  Provided you've seen
  3013. the switch at some time in the past, you can turn it on and off - but
  3014. before you've ever seen it, you can't.  Inside the room is nothing you
  3015. can see, but you can hear a dwarf breathing.  If you tell the dwarf to
  3016. turn the light on, he will.
  3017.  
  3018. *Note Answer (light switch)::.
  3019.  
  3020.  
  3021.  
  3022. 16.4 Parser error messages
  3023. ==========================
  3024.  
  3025. !!!!! Once you begin programming the parser on a large scale, you soon
  3026. reach the point where the parser's ordinary error messages no longer
  3027. appear sensible.  So that you can change the rules even at this last
  3028. hurdle, the parser calls your `ParserError' routine (if you provide
  3029. one): the argument is the error type, and you return true to tell the
  3030. parser to shut up (as you have already printed a better error message
  3031. than it would have done).  The error types are all defined as constants:
  3032.  
  3033. `STUCK_PE'
  3034.      I didn't understand that sentence.
  3035.  
  3036. `UPTO_PE'
  3037.      I only understood you as far as...
  3038.  
  3039. `CANTSEE_PE'
  3040.      You can't see any such thing.
  3041.  
  3042. `TOOLIT_PE'
  3043.      You seem to have said too little!
  3044.  
  3045. `NOTHELD_PE'
  3046.      You aren't holding that!
  3047.  
  3048. `MULTI_PE'
  3049.      You can't use multiple objects with that verb.
  3050.  
  3051. `MMULTI_PE'
  3052.      You can only use multiple objects once on a line.
  3053.  
  3054. `VAGUE_PE'
  3055.      I'm not sure what `it' refers to.
  3056.  
  3057. `EXCEPT_PE'
  3058.      You excepted something not included anyway!
  3059.  
  3060. `ANIMA_PE'
  3061.      You can only do that to something animate.
  3062.  
  3063. `VERB_PE'
  3064.      That's not a verb I recognise.
  3065.  
  3066. `SCENERY_PE'
  3067.      That's not something you need to refer to...
  3068.  
  3069. `ITGONE_PE'
  3070.      You can't see ~it~ (the spell book) at the moment.
  3071.  
  3072. `JUNKAFTER_PE'
  3073.      I didn't understand the way that finished.
  3074.  
  3075. `TOOFEW_PE'
  3076.      Only five of those are available.
  3077.  
  3078. `NOTHING_PE'
  3079.      Nothing to do!
  3080.  
  3081. `NUMBER_PE'
  3082.      I didn't understand that number.
  3083.  
  3084. `ASKSCOPE_PE'
  3085.      *whatever the scope routine prints*
  3086.  
  3087. Each time the parser gives up on a line of grammar, it has hit one of
  3088. these conditions.  A verb may have many lines of grammar; so by the time
  3089. the parser wants to print an error, all of them must have failed.  The
  3090. error message it prints is the most `interesting' one (meaning, lowest
  3091. down this list).
  3092.  
  3093.  
  3094.  
  3095.  
  3096. 17 The light and the dark
  3097. *************************
  3098.  
  3099. The library maintains light by itself, and copes with events like:
  3100.  
  3101.      a total eclipse of the Sun;
  3102.      fusing all the lights in the house;
  3103.      your lamp going out;
  3104.      a dwarf stealing it and running away;
  3105.      dropping a lit match which you were seeing by;
  3106.      putting your lamp into an opaque box and shutting the lid;
  3107.      black smoke filling up the glass jar that the lamp is in;
  3108.      the dwarf with your lamp running back into your now-dark room.
  3109.  
  3110. The point of this list is to demonstrate that light versus darkness is
  3111. tricky to get right, and that it is best left to the library.  Your code
  3112. needs only to do something like
  3113.  
  3114.      give lamp light;
  3115.      remove match;
  3116.      give glass_jar ~transparent;
  3117.      move dwarf to Dark_Room;
  3118.  
  3119. and can leave the library to sort out the consequences.  As the above
  3120. suggests, the `light' attribute means that an object is giving off
  3121. light, or that a room is currently lit (e.g., by being out of doors in
  3122. day-time).
  3123.  
  3124. If you simply never want to have darkness, and some games never do, a
  3125. sneaky way of doing it is to put the line
  3126.  
  3127.      give player light;
  3128.  
  3129. in `Initialise'.  The game works as if the player herself were glowing
  3130. enough to provide light to see by.  So there's never darkness near the
  3131. player.
  3132.  
  3133. The definition of `when there is light' is complicated, involving
  3134. recursion both up and down.  Remember that the parent of the player
  3135. object may not be a room; it may be, say, a red car whose parent is a
  3136. room.
  3137.  
  3138. There is light exactly when the parent of the player `offers light'.  An
  3139. object `offers light' if:
  3140.  
  3141.      it itself has the `light' attribute set, *or*
  3142.      any of its immediate possessions `have light', *or*
  3143.      it is see-through and its parent offers light, *or*
  3144.      it is enterable and its parent offers light;
  3145.  
  3146. while an object `has light' if:
  3147.  
  3148.      it currently has the `light' attribute set, *or*
  3149.      it is see-through and one of its immediate possessions has light.
  3150.  
  3151. The process of checking this stops as soon as light is discovered.  The
  3152. routines
  3153.  
  3154.      `OffersLight(object)' and `HasLightSource(object)'
  3155.  
  3156. which return true or false and have no side effects (that is, they
  3157. merely report on the current state without changing anything), are
  3158. available and might occasionally be useful.
  3159.  
  3160. !!!! So light is cast up and down the tree of objects.  In certain
  3161. contrived circumstances this might be troublesome: perhaps an opaque
  3162. box, whose outside is fluorescent but whose interior is dark, and which
  3163. contains an actor who needs not to have other contents of the box in
  3164. scope...  `contrived' being the word.  The dilemma could be solved by
  3165. putting an inner box in the outer one.
  3166.  
  3167. Each turn, light is reconsidered.  The presence or absence of light
  3168. affects the `Look', `Search', `LookUnder' and `Examine' actions, and
  3169. (since this is a common puzzle) also the `Go' action: you can provide a
  3170. routine called
  3171.  
  3172.      DarkToDark()
  3173.  
  3174. and if you do then it will be called when the player goes from one dark
  3175. room into another dark one.  If you want, you can take the opportunity
  3176. to kill the player off or extract some other forfeit.  If you provide no
  3177. such routine, then the player can move about freely (subject to any
  3178. rules which apply in the places concerned).
  3179.  
  3180.  
  3181. 17.0.1 Exercise: heliotropic troll
  3182. ----------------------------------
  3183.  
  3184. How would you code a troll who is afraid of the dark, and needs to be
  3185. bribed but will only accept a light source... so that the troll will be
  3186. as happy with a goldfish bowl containing a fluorescent jellyfish as he
  3187. would be with a lamp?
  3188.  
  3189. *Note Answer (heliotropic troll)::.
  3190.  
  3191.  
  3192.  
  3193.  
  3194. 18 On inventories and lists
  3195. ***************************
  3196.  
  3197.      As some day it may happen that a victim must be found
  3198.      I've got a little list -- I've got a little list
  3199.      Of society offenders who might well be underground,
  3200.      And who never would be missed
  3201.      Who never would be missed!
  3202.      
  3203.      -- W. S. Gilbert (1836--1911), `The Mikado'
  3204.  
  3205.  
  3206.  
  3207. 18.1 Producing lists
  3208. ====================
  3209.  
  3210. The library often needs to reel off a list of objects: when an `Inv'
  3211. (inventory) action takes place, for instance, or when describing the
  3212. contents of a container or a room.  Lists are difficult to print out
  3213. correctly `by hand', because there are many cases to get right
  3214. (especially when taking plurals into account).  Fortunately, the
  3215. library's list-maker is open to the public.  The routine to call is:
  3216.  
  3217.      WriteListFrom(object, style);
  3218.  
  3219. where the list will start from the given object and go along its
  3220. siblings.  (Thus, to list all the objects inside `X', list from
  3221. `child(X)'.)  What the list looks like depends on the style, which is a
  3222. bitmap you can make by adding up some of the following constants:
  3223.  
  3224. `NEWLINE_BIT'
  3225.      New-line after each entry
  3226.  
  3227. `INDENT_BIT'
  3228.      Indent each entry by depth
  3229.  
  3230. `FULLINV_BIT'
  3231.      Full inventory information after entry
  3232.  
  3233. `ENGLISH_BIT'
  3234.      English sentence style, with commas and `and'
  3235.  
  3236. `RECURSE_BIT'
  3237.      Recurse downwards with usual rules
  3238.  
  3239. `ALWAYS_BIT'
  3240.      Always recurse downwards
  3241.  
  3242. `TERSE_BIT'
  3243.      More terse English style
  3244.  
  3245. `PARTINV_BIT'
  3246.      Only brief inventory information after entry
  3247.  
  3248. `DEFART_BIT'
  3249.      Use the definite article in list
  3250.  
  3251. `WORKFLAG_BIT'
  3252.      At top level (only), only list objects which have the `workflag'
  3253.      attribute
  3254.  
  3255. The best way to use this is to experiment.  For example, a `tall'
  3256. inventory is produced by:
  3257.  
  3258.      WriteListFrom( child(player),
  3259.                     FULLINV_BIT + INDENT_BIT + NEWLINE_BIT + RECURSE_BIT );
  3260.  
  3261. and a `wide' one by:
  3262.  
  3263.      WriteListFrom( child(player),
  3264.                     FULLINV_BIT + ENGLISH_BIT + RECURSE_BIT );
  3265.  
  3266. which produce effects like:
  3267.  
  3268.      >inventory tall
  3269.      You are carrying:
  3270.        a bag (which is open)
  3271.          three gold coins
  3272.          two silver coins
  3273.          a bronze coin
  3274.        four featureless white cubes
  3275.        a magic burin
  3276.        a spell book
  3277.  
  3278.      >inventory wide
  3279.      You are carrying a bag (which is open), inside which are three gold
  3280.      coins, two silver coins and a bronze coin, four featureless white
  3281.      cubes, a magic burin and a spell book.
  3282.  
  3283. (except that the `You are carrying' part is not done by the list-maker,
  3284. and nor is the final full stop in the second example).
  3285.  
  3286. The `workflag' is an attribute which the library scribbles over from
  3287. time to time as temporary storage, but you can use it with care.  In
  3288. this case it makes it possible to specify any reasonable list.
  3289.  
  3290.  
  3291. 18.1.1 Exercise: double inventory
  3292. ---------------------------------
  3293.  
  3294. Write a `DoubleInvSub' action routine to produce an inventory like so:
  3295.  
  3296.      You are carrying four featureless white cubes, a magic burin and a
  3297.      spell book.  In addition, you are wearing a purple cloak and a
  3298.      miner's helmet.
  3299.  
  3300. *Note Answer (double inventory)::.
  3301.  
  3302.  
  3303.  
  3304. 18.2 Changing an object's description in a list
  3305. ===============================================
  3306.  
  3307. Some objects ought to print something different when they appear in
  3308. inventory lists: a wine bottle should say how much wine is left, for
  3309. instance.  By giving an object an `invent' routine, you can alter the
  3310. usual rules.
  3311.  
  3312. A typical inventory list looks like:
  3313.  
  3314.      >i
  3315.      You are carrying:
  3316.        a green cone
  3317.        a pair of hiking boots
  3318.        your satchel (which is open)
  3319.          a green cube
  3320.  
  3321. and each line goes through two stages.  Firstly, the object's indefinite
  3322. article and name are printed.  Secondly, little informative messages
  3323. like `(which is open)' are printed, and inventories are given for the
  3324. contents of open containers.
  3325.  
  3326. An object's `invent' routine gets two chances to interfere with this,
  3327. one before each stage.  So what happens is this:
  3328.  
  3329.   1. The global variable `inventory_stage' is set to 1.
  3330.  
  3331.   2. The `invent' routine is called (if there is one). If it returns
  3332.      true, stop here.
  3333.  
  3334.   3. The indefinite article and short name are printed.
  3335.  
  3336.   4. The global variable `inventory_stage' is set to 2.
  3337.  
  3338.   5. The `invent' routine is called (if there is one). If it returns
  3339.      true, go to step 8.
  3340.  
  3341.   6. One or more of the following are printed, as appropriate:
  3342.  
  3343.           (providing light)
  3344.           (being worn)
  3345.           (which is open)
  3346.           (which is closed)
  3347.  
  3348.   7. If it is an open container, its contents are inventoried.
  3349.  
  3350.   8. Linking text (such as a new-line or a comma) is printed, according
  3351.      to the current style.
  3352.  
  3353. Note that if an `invent' routine does return true, then the contents
  3354. are never reached.
  3355.  
  3356. For example, here is an `invent' routine for a matchbook:
  3357.  
  3358.              invent [ i;
  3359.                  if (inventory_stage==2) {
  3360.                      i=self.number;
  3361.                      if (i==0) print " (empty)";
  3362.                      if (i==1) print " (1 match left)";
  3363.                      if (i>1)  print " (",i," matches left)";
  3364.                  }
  3365.              ],
  3366.  
  3367. (The rest of the matchbook definition is given in the `Toyshop' example
  3368. game.)
  3369.  
  3370. !!!!! Changing the rules at `inventory_stage' 1 is kept on for more
  3371. peculiar effects (and is not really recommended).
  3372.  
  3373.  
  3374.  
  3375.  
  3376. 19 The naming of names
  3377. **********************
  3378.  
  3379.      The Naming of Cats is a difficult matter,
  3380.      It isn't just one of your holiday games;
  3381.      You may think at first I'm as mad as a hatter
  3382.      When I tell you, a cat must have THREE DIFFERENT NAMES.
  3383.      
  3384.      -- T. S. Eliot (1888--1965), `The Naming of Cats'
  3385.  
  3386.      Bulldust, coolamon, dashiki, fizgig, grungy, jirble, pachinko,
  3387.      poodle-faker, sharny, taghairm
  3388.  
  3389.      - Catachrestic words from Chambers English Dictionary
  3390.  
  3391. Providing an `invent' routine doesn't work quite so well for the match
  3392. as for the matchbook.  You might try:
  3393.  
  3394.              invent [;
  3395.                  if (inventory_stage==2) {
  3396.                      if (self has light)
  3397.                          print " (burning away)";
  3398.                      rtrue;
  3399.                  }
  3400.              ],
  3401.  
  3402. !!!! Returning true here is a trick to stop `(providing light)' from
  3403. appearing as well - after all, that's redundant.
  3404.  
  3405. This does work but there's a better way, which is to change the object's
  3406. short name itself, from `unlit match' to `lit match' say.  So another
  3407. property, called `short_name', is available.  Normally, the short name
  3408. of an object is given in the header of the object definition.  But if a
  3409. `short_name' routine is given, then whenever the game wants to write
  3410. out the name of the object, the following happens:
  3411.  
  3412.   1. If the `short_name' is a string, it's printed and that's all.
  3413.  
  3414.   2. If it is a routine, then it is called.  If it returns true, that's
  3415.      all.
  3416.  
  3417.   3. The `real' short name (the one in the object header) is printed.
  3418.  
  3419. So, as promised, here's the better way to code the match:
  3420.  
  3421.              short_name [;
  3422.                  if (self has light) print "burning match";
  3423.                  else print "unlit match";
  3424.                  rtrue;
  3425.              ],
  3426.  
  3427. Note that rooms can also be given a `short_name' routine, which might
  3428. be useful to code, say, a grid of four hundred almost exactly similar
  3429. locations, called `Area 1' up to `Area 400'.
  3430.  
  3431. !!!! Now, though, the player is going to want to type `drop the burning
  3432. match", or `light the unlit match'.  (Indeed, there might be two
  3433. matches, only one of which can be called `unlit'.)  It's perfectly
  3434. straightforward to alter the `name' property of an object (provided one
  3435. remembers what it is: a list of (machine) words, being the byte
  3436. addresses in memory of words in the dictionary) but, again, there is a
  3437. better and more powerful way. This is to give the match object a
  3438. `parse_name' routine.
  3439.  
  3440. A `parse_name' routine is expected to try to match the text which the
  3441. user has typed (available one word at a time from the `NextWord()'
  3442. routine), and to return how many words it managed to match.  It is
  3443. required to go as far as it can, i.e., not to stop if the first word
  3444. makes sense, but to keep reading and find out how many words in a row
  3445. make sense.
  3446.  
  3447. It should return:
  3448.  
  3449. `0'
  3450.      if the text didn't make any sense at all,
  3451.  
  3452. `k'
  3453.      if k words in a row of the text seem to refer to the object, or
  3454.  
  3455. `-1'
  3456.      to make the parser just do what it would normally do.
  3457.  
  3458. For example:
  3459.  
  3460.      Nearby  thing "weird thing"
  3461.       with   parse_name [ i;
  3462.                  while (NextWord()=='weird' or 'thing') i++;
  3463.                  return i;
  3464.              ];
  3465.  
  3466. This definition duplicates (very nearly) what the parser would have done
  3467. if the weird thing had been defined as:
  3468.  
  3469.      Nearby  thing "weird thing"
  3470.       with   name "weird" "thing";
  3471.  
  3472. Which isn't very useful.  But the match can now be coded up with
  3473.  
  3474.              parse_name [ i j;
  3475.                  if (self has light) j='burning';
  3476.                  else j='unlit';
  3477.                  while (NextWord()=='match' or j) i++;
  3478.                  return i;
  3479.              ],
  3480.  
  3481. so that `burning' only applies when it is, and similarly `unlit'.
  3482. (Actually the parser automatically recognises `unlit' and `lit', so this
  3483. last part was unnecessary.)
  3484.  
  3485.  
  3486.  
  3487.  
  3488. 20 Plural names and groups of similar objects
  3489. *********************************************
  3490.  
  3491.      Abiit ad plures.
  3492.      
  3493.      -- Petronius (?--c. 66), `Cena Trimalchionis'
  3494.  
  3495. A notorious problem for adventure game parsers is to handle a collection
  3496. of, say, ten gold coins, allowing the player to use them independently
  3497. of each other, while gathering them together into groups in descriptions
  3498. and inventories.  This is relatively easy in Inform, and only in really
  3499. hard cases do you have to provide code.
  3500.  
  3501. There are two problems to be overcome: firstly, the game has to be able
  3502. to talk to the player in plurals, and secondly vice versa.  First, then,
  3503. game to player:
  3504.  
  3505.      Class   gold_coin_class
  3506.       with   name "gold" "coin",
  3507.              plural "gold coins";
  3508.  
  3509. (and similar silver and bronze coin classes here)
  3510.  
  3511.      Object  bag "bag"
  3512.       with   name "bag"
  3513.       has    container open openable;
  3514.  
  3515.      Nearby co1 "gold coin"   class gold_coin_class;
  3516.      Nearby co2 "gold coin"   class gold_coin_class;
  3517.      Nearby co3 "gold coin"   class gold_coin_class;
  3518.      Nearby co4 "silver coin" class silver_coin_class;
  3519.      Nearby co5 "silver coin" class silver_coin_class;
  3520.      Nearby co6 "bronze coin" class bronze_coin_class;
  3521.  
  3522. Now we have a bag of six coins.  The player looking inside the bag will
  3523. get
  3524.  
  3525.      >look inside bag
  3526.      In the bag are three gold coins, two silver coins and a bronze coin.
  3527.  
  3528. How does the library know that the three gold coins are the same as each
  3529. other, but the others different?  It doesn't look at the classes but the
  3530. names.  It will only group together things which:
  3531.  
  3532.   1. have a `plural' set,
  3533.  
  3534.   2. are `indistinguishable' from each other.
  3535.  
  3536. Indistinguishable means they have the same `name' words as each other
  3537. (possibly in a different order), so that nothing the player can type
  3538. will separate the two.
  3539.  
  3540. !!!! Actually, the library is cleverer than this.  What it groups
  3541. together depends slightly on the context of the list it's writing out.
  3542. When it's writing a list which prints out details of which objects are
  3543. providing light, for instance (like an inventory), it won't group
  3544. together two objects if one is lit and the other isn't.  Similarly for
  3545. objects with visible possessions or which can be worn.
  3546.  
  3547. !!!!! This all gets even more complicated when the objects have a
  3548. `parse_name' routine supplied, because then the library can't use the
  3549. `name' fields to tell them apart.  If they have different `parse_name'
  3550. routines, it decides that they're different.  But if they have the same
  3551. `parse_name' routine, there is no alternative but to ask them.  What
  3552. happens is that
  3553.  
  3554.   1. A variable called `parser_action' is set to `##TheSame';
  3555.  
  3556.   2. Two variables, called `parser_one' and `parser_two' are set to the
  3557.      two objects in question;
  3558.  
  3559.   3. Their `parse_name' routine is called.  If it returns:
  3560.     `-1'
  3561.           the objects are declared `indistinguishable',
  3562.  
  3563.     `-2'
  3564.           they are declared different.
  3565.  
  3566.   4. Otherwise, the usual rules apply and the library looks at the
  3567.      ordinary `name' fields of the objects.
  3568.  
  3569. (`##TheSame' is a fake action.) The implementation of the `Spellbreaker
  3570. cubes' in the `Balances' game is an example of such a routine (so that
  3571. if the player writes the same name on several of the cubes, they become
  3572. grouped together).  Note that this whole set-up is such that if the
  3573. author of the `parse_name' routine has never read this paragraph, it
  3574. doesn't matter and the usual rules take their course.
  3575.  
  3576. !!!!! You may even want to provide a `parse_name' routine just to speed
  3577. up the process of telling two objects apart - if there were 30 gold
  3578. coins the parser will be doing a lot of work comparing all their names,
  3579. but you can make the decision much faster.
  3580.  
  3581. Secondly, the player talking to the computer.  This goes a little
  3582. further than just copies of the same object: many games involve
  3583. collecting a number of similar items, say a set of nine crowns in
  3584. different colours. Then you'd want the parser to recognise things like:
  3585.  
  3586.      > drop all of the crowns except green
  3587.      > drop the three other crowns
  3588.  
  3589. even though the crowns are not identical.  The simple way to do this is
  3590. just to put `"crowns"' in their name fields, and this works perfectly
  3591. well most of the time.
  3592.  
  3593. !!!!! But it isn't ideal, because then the parser will think
  3594.  
  3595.      > drop crowns
  3596.  
  3597. refers to a single object, and won't deduce that the player wants to
  3598. pick up all the sensibly available crowns.  So the complicated (but
  3599. better way) is to make the `parse_name' routine tell the parser that
  3600. yes, there was a match, but that it was a plural.  The way to do this
  3601. is to set `parser_action' to `##PluralFound' (another fake action).
  3602. So, for example:
  3603.  
  3604.      Class   crown_class
  3605.       with   parse_name [ i j;
  3606.                  for (::) {
  3607.                      j=NextWord();
  3608.                      if (j=='crown' or j==self.name) i++;
  3609.                      else {
  3610.                          if (j=='crowns') {
  3611.                              parser_action=##PluralFound;
  3612.                              i++;
  3613.                          }
  3614.                          else return i;
  3615.                      }
  3616.                  }
  3617.              ];
  3618.  
  3619.  
  3620. 20.0.1 Exercise: cherubim
  3621. -------------------------
  3622.  
  3623. Write a `cherub' class so that if the player tries to call them
  3624. `cherubs', a message like `I'll let this go by for now, but the plural
  3625. of cherub is cherubim" appears.
  3626.  
  3627. *Note Answer (cherubim)::.
  3628.  
  3629.  
  3630.  
  3631.  
  3632. 21 Miscellaneous constants and scoring
  3633. **************************************
  3634.  
  3635. Some game rules can be altered by defining `constants' at the start of
  3636. the program, before the library files are included.  Two constants it
  3637. *must* provide are the strings `Story' and `Headline':
  3638.  
  3639.      Constant Story "ZORK II";
  3640.      Constant Headline "^An Interactive Plagiarism^\
  3641.          Copyright (c) 1993 by Ivan O. Ideas.^";
  3642.  
  3643. All the rest are optional.
  3644.  
  3645.  
  3646.  
  3647. 21.1 Limiting the objects carried by the player
  3648. ===============================================
  3649.  
  3650. The library won't allow the player to carry an indefinite number of
  3651. objects: the limit allowed is the constant `MAX_CARRIED', which you may
  3652. define if you wish.  If you don't define it, it's 100, which roughly
  3653. removes the rule.  (In fact you can change this `live', in that it is
  3654. actually `player.capacity' which is consulted; the only use of
  3655. `MAX_CARRIED' is to set this up to an initial value.)
  3656.  
  3657. If you define `SACK_OBJECT' to be some container, then the player will
  3658. automatically put old, least-used objects away in it as the game
  3659. progresses, provided it is being carried.  This is a feature which
  3660. endears the designer greatly to players.
  3661.  
  3662.  
  3663.  
  3664. 21.2 Providing closing credits
  3665. ==============================
  3666.  
  3667. Another constant is `AMUSING_PROVIDED'.  If you define this, the
  3668. library knows to put an `amusing' option on the menu after the game is
  3669. won.  It will then call `Amusing()' from your code when needed.  You
  3670. can use this to roll closing credits, or tell the player various
  3671. strange things about the game, now that there's no surprise left to
  3672. spoil.
  3673.  
  3674.  
  3675.  
  3676. 21.3 The scoring system
  3677. =======================
  3678.  
  3679. The other constants you are allowed to define help the score routines
  3680. along.  There are two scoring systems provided by the library, side by
  3681. side: you can use both or neither.  (You can always do what you like to
  3682. the `score' variable in any case.)  One scores points for getting
  3683. certain items or reaching certain places; the other for completing
  3684. certain actions.  The constants are:
  3685.  
  3686. `MAX_SCORE'
  3687.      The maximum game score (by default 0)
  3688.  
  3689. `NUMBER_TASKS'
  3690.      Number of individual `tasks' to perform (1)
  3691.  
  3692. `OBJECT_SCORE'
  3693.      Bonus for first picking up a `scored' object (4)
  3694.  
  3695. `ROOM_SCORE'
  3696.      Bonus for first entering a `scored' room (5)
  3697.  
  3698. and then the individual tasks have scores, as follows:
  3699.  
  3700.      Global task_scores initial t1 t2 ... tn;
  3701.  
  3702. Within your code, when a player achieves something, call
  3703. `Achieved(task)' to mark that the task has been completed.  It will
  3704. only award points if this task has not been completed before.
  3705.  
  3706. There do not have to be any `tasks': there's no need to use the scoring
  3707. system provided.  Tasks (and the verb `full' for full score) will only
  3708. work at all if you define the constant `TASKS_PROVIDED'.
  3709.  
  3710. A routine called `PrintRank', which you can provide if you want, gets
  3711. the chance to print something additional to the score, such as
  3712. rankings.  For instance:
  3713.  
  3714.      [ PrintRank;
  3715.          print ", earning you the rank of ";
  3716.          if (score >= 348) "Grandmaster Adventurer!";
  3717.          if (score >= 330) "Master, first class.";
  3718.          if (score >= 300) "Master, second class.";
  3719.          if (score >= 200) "Junior Master.";
  3720.          if (score >= 130) "Seasoned Adventurer.";
  3721.          if (score >= 100) "Experienced Adventurer.";
  3722.          if (score >= 35)  "Adventurer.";
  3723.          if (score >= 10)  "Novice.";
  3724.          "Amateur.";
  3725.      ];
  3726.  
  3727. `PrintTaskName' prints the name of a game task (such as `driving the
  3728. car').  Of course, this is only ever called in a game with
  3729. `TASKS_PROVIDED' defined.  For instance,
  3730.  
  3731.      [ PrintTaskName ach;
  3732.          if (ach==0) "eating a sweet";
  3733.          if (ach==1) "driving the car";
  3734.          if (ach==2) "shutting out the draught";
  3735.          if (ach==3) "building a tower of four";
  3736.          if (ach==4) "seeing which way the mantelpiece leans";
  3737.      ];
  3738.  
  3739. Normally, an Inform game will print messages like
  3740.  
  3741.      [Your score has gone up by three points.]
  3742.  
  3743. when the score changes (by whatever means).  The player can turn this on
  3744. and off with the `notify' verb; by default it is on.  You can alter the
  3745. flag `notify_mode' yourself to control this.
  3746.  
  3747.  
  3748.  
  3749. 21.4 Asking `yes or no' questions of the player
  3750. ===============================================
  3751.  
  3752. Sometimes you want to ask the player a yes/no question.  If so, call
  3753. `YesOrNo()', a library routine: it returns true/false accordingly (and
  3754. doesn't print any question, which is up to you).  This saves a lot of
  3755. bother programming the parser.
  3756.  
  3757.  
  3758.  
  3759. 21.5 Replacing library routines
  3760. ===============================
  3761.  
  3762. !!!!! Occasionally you need to rewrite one of the library routines.
  3763. But the danger of doing so is that it is then necessary to keep a copy
  3764. of the library for every game, which is clearly unsatisfactory.  So: for
  3765. example, if the directive
  3766.  
  3767.      REPLACE BurnSub;
  3768.  
  3769. is placed in your file *before the library files are included*, Inform
  3770. ignores the definition of `BurnSub' in the library files.  (You then
  3771. have to define a routine called `BurnSub' yourself, or Inform will
  3772. complain that the program refers to a routine which isn't there.)  And
  3773. this is the very last resort, and so the end of the manual proper.
  3774.  
  3775.  
  3776.  
  3777.  
  3778. 22 Debugging verbs and tracing
  3779. ******************************
  3780.  
  3781.      If builders built buildings the way programmers write programs, the
  3782.      first woodpecker that came along would destroy civilisation.
  3783.  
  3784.      - old computing adage
  3785.  
  3786.  
  3787.  
  3788. 22.1 Debugging verbs
  3789. ====================
  3790.  
  3791. The two problems with debugging a game are working out exactly what it's
  3792. doing, and making things happen which wouldn't normally be allowed (such
  3793. as giving yourself the trident now rather than playing for two hours to
  3794. find it).
  3795.  
  3796. Inform provides a small suite of debugging verbs to help with this, but
  3797. only if the game defines the constant `DEBUG' before including the
  3798. library files.  (Just in case you forget to take this out again, the
  3799. letter D appears in the game banner to indicate this.)
  3800.  
  3801. You then get the following verbs, which can be used at any time in play:
  3802.  
  3803.      purloin ANYTHING
  3804.      abstract ANYTHING to ANYTHING
  3805.      goto NUMBER
  3806.      tree       tree THING
  3807.      actions    actions on    actions off
  3808.      routines   routines on   routines off
  3809.      timers     timers on     timers off
  3810.      trace      trace on      trace off    trace 1 TO 5
  3811.  
  3812. You can `purloin' any item or items in your game at any time, wherever
  3813. you are.  You can likewise `abstract' any item to any other item
  3814. (meaning: move it to the other item).  To get a listing of the objects
  3815. in the game and how they contain each other, use `tree', and to see the
  3816. possessions of one of them alone, use `tree THAT'.  Finally, you can go
  3817. to any object: but since rooms don't have names understood by the
  3818. parser, you have to give the object number of the place you want to go
  3819. to.  (The `tree' listing will tell you these numbers.)
  3820.  
  3821. Turning on `actions' gives a trace of all the actions which take place
  3822. in the game (the parser's, the library's or yours); turning on
  3823. `routines' traces every object routine (such as `before' or `life')
  3824. that is ever called, except for `short_name' (as this would look
  3825. chaotic, especially on the status line).  Turning on `timers' shows the
  3826. state of all active timers and daemons each turn.
  3827.  
  3828.  
  3829.  
  3830. 22.2 `Infix', Inform's debugger
  3831. ===============================
  3832.  
  3833. Infix, Dilip Sequeira's source-level debugger for Inform, is currently
  3834. in an advanced state of preparation: it is an enhanced form of Mark
  3835. Howell's Zip interpreter providing for breakpoints, tracing and so
  3836. forth.  It should fairly soon be publically archived with the rest of
  3837. the Inform project.
  3838.  
  3839. !!!! For Infix's benefit, Inform (if compiling with the option set)
  3840. produces a file of `debugging information' (cross-references of the game
  3841. file with the source code), and anyone interested in writing an Inform
  3842. utility program may want to know the format of this file: see the short
  3843. C program Infact which prints out the debugging information file in
  3844. English.
  3845.  
  3846.  
  3847.  
  3848. 22.3 How to crash an interpreter
  3849. ================================
  3850.  
  3851. On most interpreters, though, run-time crashes are mysterious (because
  3852. they were written on the assumption that all existing Infocom game files
  3853. were free from error).  Zip is rather more generous and will usually
  3854. tell you why and where the problem is; given a game file address you can
  3855. work back to the problem point in the source either with Mark Howell's
  3856. txd (disassembler) or by running Inform with the assembler trace option
  3857. on.
  3858.  
  3859. Here are all the ways I know to crash an interpreter at run-time (with
  3860. high-level Inform code, that is; if you insist on using assembly
  3861. language or the `indirect' function you're raising the stakes),
  3862. arranged in decreasing order of likelihood:
  3863.  
  3864.    * Writing to a property of an object which it hasn't got;
  3865.  
  3866.    * Dividing by zero, possibly by calling `random(0)';
  3867.  
  3868.    * Giving a string or numerical value for a property which can only
  3869.      legally hold a routine, such as `before', `after' or `life';
  3870.  
  3871.    * Applying `parent', `child' or `children' to the `nothing' object;
  3872.  
  3873.    * Using `print object' on the `nothing' object, or for some object
  3874.      which doesn't exist (always use the routines `DefArt', `CDefArt'
  3875.      or `PrintShortName' as appropriate, which are safeguarded and
  3876.      anyway implement higher-level features);
  3877.  
  3878.    * Using `print_addr' or `print_paddr' to print from an address
  3879.      outside the memory map of the game file, or an address at which no
  3880.      string is present (this will result in random text appearing,
  3881.      possibly including unprintable characters, which may conceivably
  3882.      crash your terminal);
  3883.  
  3884.    * Setting the `location' variable to zero, or some non-existent
  3885.      object, since the interpreter prints the name of this object on the
  3886.      status line; in any case it is safer to use `PlayerTo' than to
  3887.      meddle directly with this;
  3888.  
  3889.    * Running out of stack space in a recursive loop (though this has
  3890.      never actually happened to anyone I know of).
  3891.  
  3892.  
  3893.  
  3894. 22.4 Tracing the parser
  3895. =======================
  3896.  
  3897. !!!! There are times when it's hard to work out what the parser is up to
  3898. and why (actually, most times are like this).  The parser is written in
  3899. levels, the lower levels of which are murky indeed.  Most of the
  3900. interesting things happen in the middle levels, and these are the ones
  3901. for which tracing is available.  The levels which can be traced are:
  3902.  
  3903. Level 1
  3904.      Grammar lines
  3905.  
  3906. Level 2
  3907.      Individual tokens
  3908.  
  3909. Level 3
  3910.      Object list parsing
  3911.  
  3912. Level 4
  3913.      Resolving ambiguities and making choices of object(s)
  3914.  
  3915. Level 5
  3916.      Comparing text against an individual object
  3917.  
  3918. `trace' or `trace on' give only level 1 tracing.  Be warned: `trace
  3919. five' can produce reams of text when you try anything at all
  3920. complicated: but you do sometimes want to see it, to get a list of
  3921. exactly everything that is in scope and when.  There are two levels
  3922. lower than that but they're too busy doing dull spade-work to waste time
  3923. on looking at `parser_trace'.  (There's also a level 0, but it consists
  3924. mostly of making arrangements for level 1, and isn't very interesting.)
  3925.  
  3926. !!!!! Finally, though this is a drastic measure, you can always compile
  3927. your game `-g' (`debugging code') which gives a listing of every
  3928. routine ever called and their parameters.  This produces an enormous
  3929. melée of output.  (In Inform 5.3, though not earlier versions, you can
  3930. declare a routine with an asterisk `*' as its first local variable,
  3931. which produces such tracing only for that one routine.)
  3932.  
  3933.  
  3934.  
  3935.  
  3936. 23 Limitations on the run-time format
  3937. *************************************
  3938.  
  3939.      How wide the limits stand
  3940.      Between a splendid and an happy land.
  3941.      
  3942.      -- Oliver Goldsmith (1728--1774), `The Deserted Village'
  3943.  
  3944. The Infocom run-time format is well-designed, and has three major
  3945. advantages: it is compact, widely portable and can be quickly executed.
  3946. Nevertheless, like any rigidly defined format (which it clearly must
  3947. be), it imposes limitations.  These are not by any means pressing.
  3948. Inform itself has a flexible enough memory-management system not to
  3949. impose artificial limits on numbers of objects and the like.
  3950.  
  3951. There are two sizes of game available: Standard (or version 3) and
  3952. Advanced (or version 5).  Always use the latter if you can; it is very
  3953. much to be preferred.  (There are very slight risks associated with
  3954. exotic assembly-language coding in Advanced games: but unless you
  3955. deviate far from normal Inform practice, and code on a very low level,
  3956. these will never trouble you.)  There are still 8-bit computers in use
  3957. which are too small for Advanced games, but most people should have no
  3958. problem.
  3959.  
  3960. *Memory*
  3961.      The total size of a Standard game is at most 128K; of an Advanced
  3962.      game, 256K.  Because games are encoded in a very compressed form,
  3963.      and because the centralised library of Inform makes the compiler
  3964.      fairly efficient in terms of not duplicating code, even 128K
  3965.      allows for a game at least half as large again as a typical
  3966.      old-style Infocom game.  No game yet written under Inform has
  3967.      reached the 256K mark, not even the final version of `Curses' (at
  3968.      224K, already substantially bigger and denser than any Infocom
  3969.      game).
  3970.  
  3971. *Vocabulary*
  3972.      There is no theoretical limit, and vocabularies in excess of 2000
  3973.      are quite sensibly possible.  (A typical large game will muster
  3974.      1000.)
  3975.  
  3976. *Dictionary resolution*
  3977.      In Standard games, dictionary words are truncated to their first 6
  3978.      letters, which can be a nuisance; in Advanced, 9 letters, which
  3979.      never is.
  3980.  
  3981. *Attributes, properties, names*
  3982.      Standard games only provide 32 attributes, 30 properties and at
  3983.      most 8 bytes of data per property: the library consumes most of
  3984.      this ration, and the 8 bytes restriction means that an object can
  3985.      only have four words in its `name'.  This is perfectly manageable,
  3986.      if unsatisfactory.  Advanced games, which provide 48 attributes, 62
  3987.      properties and 64 bytes of data (hence 32 names), effectively make
  3988.      none of these restrictions serious.
  3989.  
  3990. *Special effects*
  3991.      Standard games cannot have special effects such as bold face and
  3992.      underlining.  *Note Styles::.
  3993.  
  3994. *Objects*
  3995.      Standard games can have at most 255 objects, enough for a large
  3996.      Infocom-size game but not much more.  Advanced games have no such
  3997.      restriction, the number being in principle unlimited.  Objects
  3998.      cannot dynamically be created or destroyed, but this is imitated
  3999.      easily enough.
  4000.  
  4001. *Global variables*
  4002.      There can only be 240 of these, and the Inform compiler uses 5 as
  4003.      scratch space, while the library uses slightly over 100; but since
  4004.      a typical game uses only a dozen of its own, code being almost
  4005.      always object-oriented, the restriction is never even nearly felt.
  4006.      (Recall that arrays take only one global each.)
  4007.  
  4008. *`Undo'*
  4009.      Standard games do not provide an `undo' verb, but Advanced ones (or
  4010.      rather, the Inform library when compiled on such) do.
  4011.  
  4012. !!!! There is a yet larger Infocom format, version 6, which lifts even
  4013. the mild restrictions of version 5 games, with memory maps of up to 600K
  4014. or so: version 6 has only recently been fully deciphered, but Inform is
  4015. already capable of producing such files, and Mark Howell's `Zip'
  4016. interpreter is (at time of writing) making good progress in running
  4017. them.  A 600K Inform game would be gargantuan: by the time one comes
  4018. along, there should be no problem in running it.
  4019.  
  4020. !!!!! Having said all this, if memory does become short, there is a
  4021. standard mechanism for saving about 8-10% of the memory.  Inform does
  4022. not usually trouble to, since there's very seldom the need, and it makes
  4023. the compiler run about 10% slower.  What you need to do is define
  4024. abbreviations.  For instance, the directive
  4025.  
  4026.      Abbreviate " the ";
  4027.  
  4028. (placed before any text appears) will cause the string ` the ' to be
  4029. internally stored as a single `letter', saving memory every time it
  4030. occurs (about 2500 times in `Curses', for instance).  You can have up to
  4031. 64 abbreviations.  A good list of abbreviations can be found in the
  4032. `Technical Manual': basically, avoid proper nouns and instead pick on
  4033. short combinations of a space and common two- or three-letter blocks.
  4034. You can even get Inform to work out by itself what a good stock of
  4035. abbreviations would be: but be warned, this makes the compiler run about
  4036. 29000% slower.
  4037.  
  4038.  
  4039.  
  4040.  
  4041. 24 A very few, not very special effects
  4042. ***************************************
  4043.  
  4044.      Yes, all right, I won't do the menu... I don't think you realise
  4045.      how long it takes to do the menu, but no, it doesn't matter, I'll
  4046.      hang the picture now.  If the menus are late for lunch it doesn't
  4047.      matter, the guests can all come and look at the picture till they
  4048.      are ready, right?
  4049.  
  4050.      - John Cleese and Connie Booth, `Fawlty Towers'
  4051.  
  4052. As the previous section suggested, some special effects are not to be
  4053. encouraged: they reduce portability a little, and anyway Inform is for
  4054. text games.
  4055.  
  4056.  
  4057.  
  4058. 24.1 The status line
  4059. ====================
  4060.  
  4061. The status line is perhaps the most distinctive feature of Infocom games
  4062. in play.  This is the (usually highlighted) bar across the top of the
  4063. screen.  Usually, the game automatically prints the current game
  4064. location, and either the time or the score and number of turns taken.
  4065. It has the score/turns format unless the directive
  4066.  
  4067.      Statusline time;
  4068.  
  4069. is present, in which case it shows the game's 24-hour clock.
  4070.  
  4071. !!!!! If you *really* want to change this, then `Replace' the parser's
  4072. private `DrawStatusLine' routine.  But be sure to test the result on
  4073. more than one interpreter, in case you've made a mistake which doesn't
  4074. show up on one quirky implementation.  (In any case, you can only
  4075. change it at all on Advanced games.)
  4076.  
  4077.  
  4078. 24.1.1 Exercise: status line
  4079. ----------------------------
  4080.  
  4081. Alter the `Advent' example game to display the number of treasures
  4082. found instead of the score and turns on the status line.
  4083.  
  4084. *Note Answer (status line)::.
  4085.  
  4086.  
  4087.  
  4088. 24.2 Character graphics
  4089. =======================
  4090.  
  4091. About character graphic drawings: on some machines, text will by default
  4092. be displayed in a proportional font (i.e., one in which the width of a
  4093. letter depends on what it is, so that for example an `i' will be
  4094. narrower than an `m').  If you want to display a diagram made up of
  4095. letters, such as a map, you will have to turn this off, for which the
  4096. `font' command is provided.  Write `font off' before printing character
  4097. graphics, and remember to write `font on' again afterwards.
  4098.  
  4099. *WARNING:* Don't turn the `font' on and off in the middle of a line;
  4100. this doesn't look right on some machines.
  4101.  
  4102.  
  4103.  
  4104. 24.3 Putting quotes in boxes
  4105. ============================
  4106.  
  4107. A distinctive feature of later Infocom games was their use of epigrams.
  4108. Inform can do this, too, but only for Advanced games.  The assembly
  4109. language required is easy but a nuisance, so there is a command to do
  4110. it, `box'.  For example,
  4111.  
  4112.      box "Beware of the Dog";
  4113.  
  4114. or
  4115.  
  4116.      box "I might repeat to myself, slowly and soothingly,"
  4117.          "a list of displays beautiful from minds profound;"
  4118.          "if I can remember any of the damn things."
  4119.          ""
  4120.          "-- Dorothy Parker";
  4121.  
  4122. Note that a string of lines is given (without intervening commas) and
  4123. that a blank line is given by a null string.  Remember that the text
  4124. cannot be too wide or it will look awful on a small screen.
  4125.  
  4126. The author takes the view that this device is amusing for irrelevant
  4127. displays but irritating when it conveys vital information (such as,
  4128. `Beware of the Dog', for instance).  Also, some people might be running
  4129. your game on a laptop with a vertically challenged screen, so it is
  4130. polite to provide a `quotes off' verb.
  4131.  
  4132.  
  4133.  
  4134. 24.4 Interactive menus
  4135. ======================
  4136.  
  4137. Sometimes one would like to provide a menu of text options (for
  4138. instance, when producing instructions which have several topics, or when
  4139. giving clues).  This can be done with the `DoMenu' routine, which
  4140. imitates the traditional `Invisiclues' style.  However, it only looks
  4141. good for Advanced games; for Standard games, it's simply textual.  (In
  4142. an Advanced game, by setting `pretty_flag=0' you can get this simple
  4143. text version instead; which is a good idea for machines with very small
  4144. screens.)
  4145.  
  4146. Here is a typical call to `DoMenu':
  4147.  
  4148.      DoMenu("There is information provided on the following:^\
  4149.              ^     Instructions for playing\
  4150.              ^     The history of this game\
  4151.              ^     Credits^",
  4152.              #r$HelpMenu, #r$HelpInfo);
  4153.  
  4154. Note the layout, and especially the carriage returns.  The second and
  4155. third arguments are themselves routines: the notation `#r$', seldom
  4156. seen in high-level Inform, allows routine names to become ordinary
  4157. numerical values.  The first routine, in this case called `HelpMenu',
  4158. is supposed to look at the variable `menu_item'.  In the case when this
  4159. is zero, it should return the number of entries in the menu (3 in the
  4160. example).  In any case it should set `item_name' to the title for the
  4161. page of information for that item; and `item_width' to half its length
  4162. in characters (this is used to centre titles on the screen: it is
  4163. unfortunately tricky for the game to compute the length of a static
  4164. string, so you have to tell it).  In the case of item 0, the title
  4165. should be that for the whole menu.
  4166.  
  4167. The second routine, `HelpInfo' above, should simply look at `menu_item'
  4168. (1 to 3 above) and print the text for that selection.  After this
  4169. returns, normally the game prints `Press [Space] to return to menu' but
  4170. if the value 2 is returned it doesn't wait.
  4171.  
  4172. Menu items can safely launch whole new menus, and it is easy to make a
  4173. tree of these (which will be needed when it comes to providing hints
  4174. across any size of game).
  4175.  
  4176.  
  4177. 24.4.1 Exercise: invisiclues
  4178. ----------------------------
  4179.  
  4180. Code an `Invisiclues'-style sequence of hints for a puzzle, revealed one
  4181. at a time, as a menu item.
  4182.  
  4183. *Note Answer (invisiclues)::.
  4184.  
  4185.  
  4186.  
  4187. 24.5 Text styles
  4188. ================
  4189.  
  4190. Finally, though it should only be used sparingly (and again is
  4191. restricted to Advanced games), one can change the text style.  The
  4192. command for this is `style' and its effects are loosely modelled on the
  4193. VT100 (design of terminal).  The style can be `style roman', `style
  4194. bold', `style reverse' or `style underline'.  Again, remember that poor
  4195. terminals may not be able to display these, so you shouldn't hide
  4196. crucial information in them.
  4197.  
  4198.  
  4199.  
  4200.  
  4201. 25 Dirty tricks
  4202. ***************
  4203.  
  4204. !!!!! The dirtiest tricks of all are those which bypass Inform's higher
  4205. levels and program the Z-machine directly.  There is an element of
  4206. danger in assembly language programming, in that some combinations of
  4207. unusual opcodes can look ugly on some incomplete or wrongly-written
  4208. interpreters: so if you're doing anything complicated, test it as widely
  4209. as possible.  Note that none of the interesting effects work at all on
  4210. Standard games, only Advanced games.
  4211.  
  4212. The best-researched and most reliable interpreter available by far is
  4213. Mark Howell's Zip; as it's also the fastest, it will hopefully `take
  4214. over' entirely.  Next comes the InfoTaskForce, which is thorough and
  4215. should give no serious trouble, but was written when the format was a
  4216. little less well understood, and so (in some ports) gets some (rare)
  4217. screen effects wrong.  (It also lacks an `undo' feature, so the `undo'
  4218. verb automatically provided by the library routines won't work under
  4219. ITF.)  The other two publically-available interpreters are pinfocom and
  4220. zterp, but these are unable to run Advanced games.  In the last resort,
  4221. sometimes it's possible to use one of Infocom's own supplied
  4222. interpreters with a different game from that it came with; but only
  4223. sometimes, as they may have inconvenient filenames `wired into them'.
  4224. The author recommends that anyone using assembly-language features get
  4225. hold of both ITF and Zip, and test on both.
  4226.  
  4227. This all sounds rather unportable, though actually the core described
  4228. below is pretty reliable.  But remember that the unportability does have
  4229. some genuine cause.  Your game may be running on a screen which is
  4230. anything from a 64 by 9 pocket organiser up to a 132 by 48 X-window.
  4231.  
  4232. Anyone wanting to really push the outer limits (say, by implementing
  4233. Space Invaders or NetHack) will need to refer to `The Specification of
  4234. the Z-Machine', which also documents Inform assembly language format.
  4235.  
  4236. Screen tricks are the commonest.  An upper-level screen (which usually
  4237. holds the status line) can be split off from the main screen:
  4238.  
  4239.      split_window n;
  4240.  
  4241. creates one which is n lines tall.  (This doesn't change the display,
  4242. and it can be resized at any time: but it needs to be tall enough to
  4243. include all the lines you want to write to, as otherwise the interpreter
  4244. may flounder: some will scroll the upper window, others won't.)  The
  4245. main screen is numbered 0, and the upper one 1; text output is switched
  4246. between them by
  4247.  
  4248.      set_window n;
  4249.  
  4250. The lower window is just a text stream whose cursor position cannot be
  4251. set: on the other hand, when it is returned to, the cursor will be where
  4252. it was before it was left.  Within the upper window, the cursor can be
  4253. moved by
  4254.  
  4255.      set_cursor line column;
  4256.  
  4257. where (1,1) is the top left character.  Printing on the upper window
  4258. overlies printing on the lower, is always done in a fixed-space font and
  4259. does not appear in a printed transcript of the game.  However, before
  4260. printing to the upper window, it is essential to change the printing
  4261. format - that is, the `buffer_mode' opcode.  Before printing, execute
  4262.  
  4263.      buffer_mode 0;
  4264.  
  4265. and when returning to the normal screen,
  4266.  
  4267.      buffer_mode 1;
  4268.  
  4269. Otherwise, dodgy interpreters (like ITF) may continue trying to split
  4270. lines at word breaks, and make a horrid mess.
  4271.  
  4272. A convenient way to clear the screen is
  4273.  
  4274.      erase_window $ffff;
  4275.  
  4276. but don't chance this in reverse video mode!  (And don't assume that
  4277. `erase_window' can erase individual windows - it should, but may not on
  4278. bad interpreters.)
  4279.  
  4280. Players can be gratuitously annoyed (on most machines, anyway) by the
  4281. `beep' opcode.  This is the only remotely portable sound effect.
  4282.  
  4283. The keyboard can be read in remarkably flexible ways, using the `aread'
  4284. and `read_char' opcodes.
  4285.  
  4286.      aread text parse time function;
  4287.  
  4288. will read from the keyboard, putting text into the `text' buffer,
  4289. tokenising it onto the end of the `parse' buffer (unless this is zero),
  4290. and calling
  4291.  
  4292.      function(time);
  4293.  
  4294. every `time' seconds that the user is thinking: the process ends if
  4295. ever this function returns true.  Thus (by `Replace'ing the `Keyboard'
  4296. routine in the library files) you could, say, move around all the
  4297. characters every ten seconds of real time.
  4298.  
  4299.      read_char 1 time function RESULT;
  4300.  
  4301. where RESULT is a variable, will store in that variable the ASCII value
  4302. of a single keypress.  Once again, the `function' is called every
  4303. `time' seconds and may stop this process early.  Function keys return
  4304. special values from 129 onwards, in the order: cursor up, down, left,
  4305. right, function key f1, ..., f12, keypad digit 0, ..., 9.
  4306.  
  4307. Leafing through the dictionary of opcodes will reveal a few other
  4308. interesting features.  It's possible to change the input and output
  4309. streams which, although only Zip gets this right, may be convenient for
  4310. debugging purposes (creating scripts of all typed commands, for
  4311. example).  Finally, there are opcodes which tokenise (that is, simply
  4312. compare dictionary entries against) arbitrary strings from arbitrary
  4313. dictionaries, and which translate small doses of ASCII to internal
  4314. Z-machine string format.  Actually, one can avoid the need for this in
  4315. many cases, by programming the parser correctly: see, for instance, the
  4316. `Balances' game which manages without these features.
  4317.  
  4318.  
  4319.  
  4320.  
  4321. A The Inform language
  4322. *********************
  4323.  
  4324. This is going to be a long appendix, full of lists and tables: but it
  4325. has to appear somewhere, if only for reference.  (Some technical
  4326. commands for internal use only are skipped over: see the `Technical
  4327. Manual' for details of these.)
  4328.  
  4329.  
  4330.  
  4331. A.1 File format
  4332. ===============
  4333.  
  4334. When Inform reads in a file, it treats a few characters in special ways.
  4335. The character `!' means the rest of the line (up to the next new-line)
  4336. is a comment, and Inform throws it away.  Tab characters are treated as
  4337. spaces.  Backslashes `\' fold strings together, so that the new-line
  4338. and all subsequent spaces are ignored.  New-lines have no significance;
  4339. statements (and directives) are separated by semicolons `;'.
  4340.  
  4341.  
  4342.  
  4343. A.2 Directives
  4344. ==============
  4345.  
  4346. These are commands directly to the Inform compiler, like `Object'.
  4347. They can, but need not, be prefaced by a hash character, `#'.  The
  4348. directives which Inform understands are:
  4349.  
  4350. `Abbreviate STRING'
  4351.      Declare an abbreviation
  4352.  
  4353. `Attribute NAME'
  4354.      Make a new attribute
  4355.  
  4356. `Class ...'
  4357.      Define a new class
  4358.  
  4359. `Constant NAME VALUE'
  4360.      Define a named constant
  4361.  
  4362. `End'
  4363.      End compilation here
  4364.  
  4365. `Endif'
  4366.      End of conditional compilation
  4367.  
  4368. `Extend ...'
  4369.      Extend the grammar for an existing verb
  4370.  
  4371. `Fake_action NAME'
  4372.      Make a new `fake action'
  4373.  
  4374. `Global NAME ...'
  4375.      Declare a global variable
  4376.  
  4377. `Ifdef NAME'
  4378.      Compile only if constant is defined
  4379.  
  4380. `Ifndef NAME'
  4381.      Compile only if constant is undefined
  4382.  
  4383. `Ifnot'
  4384.      Compile only if previous `If...' failed
  4385.  
  4386. `Ifv3'
  4387.      Compile only for Standard games
  4388.  
  4389. `Ifv5'
  4390.      Compile only for Advanced games
  4391.  
  4392. `Include FILENAME'
  4393.      Include that file here
  4394.  
  4395. `Nearby'
  4396.      Make an object inside the last `Object'
  4397.  
  4398. `Object'
  4399.      Make an object
  4400.  
  4401. `Property NAME ...'
  4402.      Make a new property
  4403.  
  4404. `Replace ROUTINE'
  4405.      Don't compile this library routine
  4406.  
  4407. `Release NUMBER'
  4408.      Set the game's Release Number
  4409.  
  4410. `Serial STRING'
  4411.      Set the game's Serial Number
  4412.  
  4413. `Statusline ...'
  4414.      Make the status line show score or time
  4415.  
  4416. `Switches SWITCHES'
  4417.      Set default compilation switches
  4418.  
  4419. `Verb ...'
  4420.      Declare the grammar for a new verb
  4421.  
  4422. The release number of a game (by default 1) is generally an edition
  4423. number; the serial number is the compilation date in the form 940924,
  4424. that is, yymmdd.  Inform sets this automatically on machines where the
  4425. date is accessible, so the `Serial' directive is provided only for use
  4426. on machines without such an internal clock.
  4427.  
  4428. !!!! Conditional compilation allows code for routines which need only
  4429. exist in some `versions' of your games.  For instance,
  4430.  
  4431.      print "Welcome to the ";
  4432.      #IFV3; print "Standard"; #IFNOT; print "Advanced"; #ENDIF;
  4433.      print " version of Zork LVI.";
  4434.  
  4435. (The `#IFNOT' clause is optional.)  Note the trailing semicolon: Inform
  4436. is not C!  Such clauses may be nested up to 32 deep, and may contain
  4437. whole routines.  They may not, however, conditionally give *part* of a
  4438. statement.  Thus, for instance,
  4439.  
  4440.      print #IFV3; "Standard"; #IFNOT; "Advanced"; #ENDIF;
  4441.  
  4442. is *not* legal.
  4443.  
  4444. !!!!! The following directives are recondite and not for public use:
  4445.  
  4446.      Default Dictionary Listsymbols Listdict Listverbs Lowstring Stub
  4447.      System_file Trace Btrace Etrace Ltrace Notrace Nobtrace Noetrace
  4448.      Noltrace
  4449.  
  4450.  
  4451.  
  4452. A.3 Variables and arrays
  4453. ========================
  4454.  
  4455. There are two kinds of variable, global and local (plus one special
  4456. one).  Variables are all two-byte integers, which are treated as signed
  4457. when it makes sense to do so (e.g., in asking whether one is positive
  4458. or not) but not when it doesn't (e.g., when it is used as an address).
  4459. Global variables must be declared before use, by the `Global' directive:
  4460.  
  4461.      Global VARNAME = INITIAL-VALUE
  4462.                       `data' SIZE
  4463.                       `string' SIZE
  4464.                       `initial' VALUE-1 ... VALUE-N
  4465.                       `initstr' TEXT
  4466.  
  4467. For instance:
  4468.  
  4469.      Global turns = 1;
  4470.      Global buffer string 120;   ! text buffer holding 120 characters
  4471.      Global task_scores initial 4 5 9 1 2 3 0;  ! a 7-byte array
  4472.      Global players_name initstr "Graham";  ! an array of 6 chars
  4473.  
  4474. When you declare a variable as an array (by `data', `string', `initial'
  4475. or `initstr') what actually happens is that Inform allocates as much
  4476. space as you ask for, somewhere inside the machine, and stores the
  4477. address of this array in the variable.  You can get at entries of the
  4478. array by
  4479.  
  4480.      buffer->entry    buffer-->entry
  4481.  
  4482. which read (or write to) the `entry'-th byte (in the case of `->') or
  4483. word (for `-->').  A `data' array is initially full of zeros, while an
  4484. `initial' array contains the given (byte) values, which all have to be
  4485. constants for obvious reasons.  A `string' array is a special kind of
  4486. `data' array: the first byte contains its length (in bytes), and the
  4487. rest are initially zero.  `initstr' is the same but initialised to the
  4488. given string.  The text here is plain ASCII, and is not encrypted as
  4489. constant strings tend to be.  (This string format is used by the
  4490. parser.)
  4491.  
  4492. In addition, a routine can have from none up to 15 local variables.
  4493.  
  4494. *WARNING:* There is also a stack, but it should be tampered with only
  4495. carefully in times of dire need.  Never call a variable `sp', as this
  4496. is the stack pointer, and if you must use the stack at all, be careful
  4497. not to leave values on it: or your game may crash 1000 turns later,
  4498. serving you right.
  4499.  
  4500.  
  4501.  
  4502. A.4 Constants
  4503. =============
  4504.  
  4505. Inform constants can take many forms.  The obvious ones are numbers,
  4506.  
  4507.      123   $ee05   $$11011001
  4508.  
  4509. being examples in decimal, hexadecimal and binary respectively.  There
  4510. are also
  4511.  
  4512. `##Action'
  4513.      (The number of) the given action
  4514.  
  4515. `"some text"'
  4516.      (The packed address of) the given string
  4517.  
  4518. `'c''
  4519.      (The ASCII code for) the given character
  4520.  
  4521. `'word''
  4522.      (The byte address of) its dictionary entry
  4523.  
  4524. There is slight potential for confusion here: `'A'' evaluates to 65,
  4525. but `'an'' to the dictionary address of the word `an'.  Note that the
  4526. construction `'sponge'' actually enters the word `sponge' into the
  4527. dictionary if it wasn't already there.  These are all legal constants:
  4528.  
  4529.      31415  -1  $ff  $$1001001  'lantern'  ##Look  'X'
  4530.      "an emerald the size of a plover's egg"
  4531.      "~Hello,~ said Peter.^~Hello, Peter,~ said Jane.^"
  4532.  
  4533.  
  4534.  
  4535. A.5 Quoted strings
  4536. ==================
  4537.  
  4538. Inside the text of a string, the character `^' is replaced by a
  4539. new-line character, and the character `~' by a double-quote mark: these
  4540. both make strings much easier to type.
  4541.  
  4542. Inside a string (under Inform 5.3 or later) `@@'NUMBER produces the
  4543. character whose ASCII value is NUMBER, and you can use this to get
  4544. untypeable characters from foreign character sets.  (Or, for example, a
  4545. literal backslash, by `@@92'.)
  4546.  
  4547. For the `@' string escape and other obscure constant forms such as
  4548. `#r$', see the `Technical Manual'.
  4549.  
  4550.  
  4551.  
  4552. A.6 Routines
  4553. ============
  4554.  
  4555. Routines start with a `[' and end with a `]'.  That is, they open with
  4556.  
  4557.      `[' ROUTINE-NAME LOCAL-VAR-1 ... LOCAL-VAR-N`;'
  4558.  
  4559. giving the names of local variables for the routine ($0\leq n\leq 15$).
  4560. The routine ends with just `];'.  (Routines embedded in object
  4561. definitions are the same, except that no routine-name is given, and they
  4562. may end in `],' if the object definition continues.)
  4563.  
  4564. The first few local variables also hold the arguments passed to the
  4565. routine when the function is called.  That is, if you have a routine
  4566.  
  4567.      [ Look from i j; ...some code...; ];
  4568.  
  4569. and it is called by `Look(attic);' then the local variable `from' will
  4570. initially have the value `attic'.  The rest all start out at zero.
  4571.  
  4572. From Inform 5.3, if the first variable is given as `*' then tracing
  4573. code is compiled to print details each time the routine is called.
  4574.  
  4575. Function calls (that is, calls to routines) are legal with between 0 and
  4576. 3 arguments, and every routine always returns a value.  If execution
  4577. runs into the `];' at the bottom, that value is `true' (or 1) for an
  4578. ordinary routine, or `false' (or 0) for an embedded one.
  4579.  
  4580.  
  4581.  
  4582. A.7 Labels
  4583. ==========
  4584.  
  4585. In case you want to `jump' around inside a routine, you can define
  4586. labels with a statement starting with a full stop, like `.labelname;'.
  4587. It is legal, though ill-advised, to jump out of one routine and into
  4588. another.  Label names are global, so the same label name can't be used
  4589. in two different routines.
  4590.  
  4591.  
  4592.  
  4593. A.8 Operators
  4594. =============
  4595.  
  4596. Arithmetic (and other) expressions can contain the following:
  4597.  
  4598. `+ -'
  4599.      plus, minus
  4600.  
  4601. `* / % & |'
  4602.      times, divide, remainder, bitwise and, bitwise or
  4603.  
  4604. `-> -->'
  4605.      byte array, word array entry
  4606.  
  4607. `. .& .#'
  4608.      property, property address, property length
  4609.  
  4610. `-'
  4611.      unary minus
  4612.  
  4613. `++ --'
  4614.      incrementing and decrementing variables (as in C)
  4615.  
  4616. The order of precedence is as shown: i.e., those on each line are
  4617. equally potent, more potent than those above but less than those
  4618. beneath.  Expressions are not allowed to contain conditions, nor
  4619. assignments: `2+(i=3/j)' is not a legal expression.  Some legal
  4620. examples:
  4621.  
  4622.      4*(x+3/y)   Fish(x)+Fowl(y)  lamp.time   buffer->5
  4623.  
  4624. Note that `++' and `--' can only be applied to variables, not to
  4625. properties or array entries.
  4626.  
  4627.  
  4628.  
  4629. A.9 Assignments
  4630. ===============
  4631.  
  4632. There are four forms allowed are:
  4633.  
  4634.      VARIABLE `=' VALUE`;'
  4635.      BYTE-ARRAY`->'ENTRY `=' VALUE`;'
  4636.      WORD-ARRAY`-->'ENTRY `=' VALUE`;'
  4637.      OBJECT`.'PROPERTY `=' VALUE`;'
  4638.  
  4639. For example:
  4640.  
  4641.      i=-15-j;   i=j-->1;   albatross.weight = albatross.weight + 1;
  4642.      (paintpot.&roomlist)-->i = location;   turns++;
  4643.  
  4644. One can also `inc' or `dec' (increment or decrement) a variable, with
  4645. `inc score;' being equivalent to the more modern `score++;'
  4646.  
  4647. Although these look logical, they are not allowed:
  4648.  
  4649.      paintpot.#roomlist = 5;
  4650.      paintpot.&roomlist = array;
  4651.  
  4652. because one cannot change the size or address of a property in play.
  4653.  
  4654. *WARNING:* A division by zero error (such as `n/0' or `n%0') may crash
  4655. the game at run time.
  4656.  
  4657. *WARNING:* Attempting to write to a property which an object does not
  4658. have may crash the game at run time.
  4659.  
  4660.  
  4661.  
  4662. A.10 Conditions
  4663. ===============
  4664.  
  4665. A simple condition is
  4666.  
  4667.      A RELATION B
  4668.  
  4669. where the relation is one of
  4670.  
  4671. `=='
  4672.      `a' equals `b'
  4673.  
  4674. `~='
  4675.      `a' doesn't equal `b'
  4676.  
  4677. `< > >= <='
  4678.      numeric (signed) comparisons
  4679.  
  4680. `has'
  4681.      object `a' has attribute `b'
  4682.  
  4683. `hasnt'
  4684.      object `a' hasnt attribute `b'
  4685.  
  4686. `in'
  4687.      object `a' is currently held by object `b'
  4688.  
  4689. `notin'
  4690.      ... is not...
  4691.  
  4692. With `==' (and `~=') only, one may also write the useful construction
  4693.  
  4694.      SOMETHING `==' V1 [`or' V2 [`or' V3]]
  4695.  
  4696. which is true if the first something is any of the values given.  (An
  4697. idiosyncracy of Inform, for `hardware reasons', is that you can only
  4698. have three).  Conditions can be combined by the `&&' and `||' operators:
  4699.  
  4700.      CONDITION1 `&&' CONDITION2
  4701.      CONDITION1 `||' CONDITION2
  4702.  
  4703. true if both, or either (respectively) are true.  These are always
  4704. tested left to right until the outcome is known.  So, for instance,
  4705.  
  4706.      i==1 || Explode(2)==2
  4707.  
  4708. does not call `Explode' if `i' is 2.  Examples of legal conditions are:
  4709.  
  4710.      i==1 or 2 or 3
  4711.      door has open || (door has locked && key in player)
  4712.  
  4713.  
  4714.  
  4715. A.11 Built-in functions
  4716. =======================
  4717.  
  4718. A very few functions are built into the language of Inform itself
  4719. (rather than written out longhand in the library files), but they
  4720. behave like any other routines.  They are:
  4721.  
  4722. `parent(obj)'
  4723.      parent of object
  4724.  
  4725. `sibling(obj)'
  4726.      sibling of object
  4727.  
  4728. `child(obj)'
  4729.      eldest child of object
  4730.  
  4731. `children(obj)'
  4732.      number of (direct) children of object
  4733.  
  4734. `eldest(obj)'
  4735.      same as `child'
  4736.  
  4737. `youngest(obj)'
  4738.      youngest child of object
  4739.  
  4740. `elder(obj)'
  4741.      elder sibling of object
  4742.  
  4743. `younger(obj)'
  4744.      same as `sibling'
  4745.  
  4746. `random(x)'
  4747.      uniformly random number between 1 and $x$
  4748.  
  4749. `indirect(addr)'
  4750.      call routine with address `addr'
  4751.  
  4752. *WARNING:* `random(0)' may cause a division by zero error.
  4753.  
  4754.  
  4755.  
  4756. A.12 Printing commands
  4757. ======================
  4758.  
  4759. A string on its own, such as
  4760.  
  4761.      "The world explodes in a puff of garlic.";
  4762.  
  4763. is printed, with a new-line, and the current routine is returned from
  4764. with return value `true', i.e., 1.  In addition:
  4765.  
  4766. `new_line'
  4767.      prints a new-line
  4768.  
  4769. `print ...'
  4770.      prints the given things
  4771.  
  4772. `print_ret ...'
  4773.      prints, new-lines and returns 1
  4774.  
  4775. `spaces n'
  4776.      prints n spaces
  4777.  
  4778. `print_addr a'
  4779.      print string at byte address `a'
  4780.  
  4781. `print_paddr a'
  4782.      print string at packed address `a'
  4783.  
  4784. `font on/off'
  4785.      turns proportional fonts on/off
  4786.  
  4787. `style ...'
  4788.      in Advanced games, sets text style
  4789.  
  4790. `box "s1" ... "sn"'
  4791.      in Advanced games, puts up display box
  4792.  
  4793. `inversion'
  4794.      prints out the current Inform version number
  4795.  
  4796. `print' and `print_ret' take a comma-separated list of things to print
  4797. out, which can be: `"strings"', `char n' (print the character with this
  4798. ASCII value) or `variable' (print out the variable as a signed number).
  4799. The text `style' can be any of
  4800.  
  4801.      roman  reverse  bold  underline
  4802.  
  4803.  
  4804.  
  4805. A.13 Manipulating objects
  4806. =========================
  4807.  
  4808. `remove obj'
  4809.      removes object from the tree
  4810.  
  4811. `move o1 to o2'
  4812.      moves `o1' to become youngest child of `o2'
  4813.  
  4814. `give obj a1 ... an'
  4815.      gives attributes to `obj'
  4816.  
  4817. Attributes beginning with a `~' are taken away rather than given.
  4818.  
  4819.  
  4820.  
  4821. A.14 Returning from routines
  4822. ============================
  4823.  
  4824. `return'
  4825.      Return true, i.e., 1
  4826.  
  4827. `return x'
  4828.      Return value $x$
  4829.  
  4830. `rtrue'
  4831.      Return true, i.e., 1
  4832.  
  4833. `rfalse'
  4834.      Return false, i.e., 0
  4835.  
  4836.  
  4837.  
  4838. A.15 Blocks of code
  4839. ===================
  4840.  
  4841. A block of code may be a single instruction or a series of several, in
  4842. which case it must be enclosed in braces `{' and `}'.  Thus, for
  4843. instance, in
  4844.  
  4845.      if (i==1)
  4846.          print "The water rises!";
  4847.      if (i==2) {
  4848.          print "The water rises further...";
  4849.          water++;
  4850.      }
  4851.  
  4852. the `if' statements contain a block of code each.  Blocks can be nested
  4853. inside each other up to 32 deep.  An `if' statement (for example) is a
  4854. single statement even when it contains a great deal of code in its
  4855. block: so, for example,
  4856.  
  4857.      if (i>1)
  4858.          if (water<10)
  4859.              "The water is beginning to worry you.";
  4860.  
  4861. is legal.  (One small exception: an `if' followed by an `else' counts
  4862. as two statements, and this means Inform handles hanging elses rather
  4863. poorly: so it's wise to brace so that `else' is clearly unambiguous.)
  4864.  
  4865.  
  4866.  
  4867. A.16 Control constructs
  4868. =======================
  4869.  
  4870. Inform provides:
  4871.  
  4872.      `if' CONDITION BLOCK1 `[else' BLOCK2`]'
  4873.      `while' CONDITION BLOCK
  4874.      `do' BLOCK `until' CONDITION
  4875.      `for ('INITIALISE`:'TEST`:'EACH TIME`)'
  4876.      `objectloop ('VARIABLE `in' OBJECT`)'
  4877.      `objectloop ('VARIABLE `from' OBJECT`)'
  4878.      `objectloop ('VARIABLE `near' OBJECT`)'
  4879.      `break'
  4880.      `jump' LABEL
  4881.  
  4882. Some of these will be familiar to most.  The `for' construct is
  4883. essentially the same as that in C, except for the colons `:' (which in
  4884. C would be semicolons).  Its carries out the initial assignment(s),
  4885. then executes the code for as long as the condition holds, executing the
  4886. end assignment after each pass through the code.  For instance,
  4887.  
  4888.      for (i=1:i<=10:i++) print i, " ";
  4889.  
  4890. counts to 10.  All three clauses are optional, and the empty condition
  4891. is always true; multiple assignments can be made.  For instance:
  4892.  
  4893.      for (i=0,j=10:i<10:i++,j--) print i, " + ", j, " = ", i+j, "^";
  4894.      for (::) print "Ha!^";
  4895.  
  4896. the latter laughing maniacally forever.
  4897.  
  4898. `break' breaks out of the current loop (not quite the same as breaking
  4899. out the current block of code: `if' statements don't count as loops in
  4900. this regard).
  4901.  
  4902. `objectloop' goes through the object tree, and is extremely useful.
  4903. `from' means from the given object through its siblings; `in' means
  4904. through all children of the given object, and `near' means through all
  4905. children of the parent of the object.  For instance, the following do
  4906. the same thing:
  4907.  
  4908.      objectloop (x in lamp) { ... }
  4909.      for (x=child(lamp): x~=0: x=sibling(x)) { ... }
  4910.  
  4911. Note that the library creates a variable called `top_object' holding
  4912. the highest existing object number: so a way to loop over every object
  4913. defined in your own code is
  4914.  
  4915.      for (i=player+1: i<=top_object: i++) ...
  4916.  
  4917. since `player' is always set to `selfobj', which is the last object
  4918. created by the library.
  4919.  
  4920. *WARNING:* When looping through the object tree, be careful if you are
  4921. altering it at the same time.  For instance,
  4922.  
  4923.      objectloop (x in rucksack) remove x;
  4924.  
  4925. is likely to go horribly wrong - it's safer not to cut down a tree
  4926. while actually climbing it.  The safe way is to keep lopping branches
  4927. off,
  4928.  
  4929.      while (child(x)~=0) remove child(x);
  4930.  
  4931.  
  4932. A.16.1 Exercise: primes
  4933. -----------------------
  4934.  
  4935. Write a routine to print out prime factorisations of numbers from 2 to
  4936. 100.
  4937.  
  4938. *Note Answer (primes)::.
  4939.  
  4940.  
  4941.  
  4942. A.17 Invoking actions
  4943. =====================
  4944.  
  4945. The commands
  4946.  
  4947.      `<' ACTION `['FIRST-OBJECT `['SECOND-OBJECT`]]' `>'
  4948.      `<<' ACTION `['FIRST-OBJECT `['SECOND-OBJECT`]]' `>>'
  4949.  
  4950. cause the given actions to take place.  In the latter case, the current
  4951. routine then returns 1, or true.
  4952.  
  4953.  
  4954.  
  4955.  
  4956. B Library, properties and attributes
  4957. ************************************
  4958.  
  4959.      A Model must be built which will get everything in without a
  4960.      clash; and it can do this only by becoming intricate, by mediating
  4961.      its unity through a great, and finely ordered, multiplicity.
  4962.  
  4963.      - C. S. Lewis (1898-1963), `The Discarded Image'
  4964.  
  4965.  
  4966.  
  4967. B.1 Library objects
  4968. ===================
  4969.  
  4970. The library defines the following special objects:
  4971.  
  4972. `compass'
  4973.      To contain the directions.  A direction object provides a
  4974.      `door_dir' property, and should have the `direction' attribute.  A
  4975.      compass direction with `enterable', if there is one (which there
  4976.      usually isn't), will have an `Enter' action converted to `Go'.
  4977.  
  4978. `n_obj'
  4979.      Both the object signifying the abstract concept of `northness',
  4980.      and the `north wall' of the current room.  (Thus, if a player
  4981.      types `examine the north wall' then the action `Examine n_obj'
  4982.      will be generated.) Its `door_dir' property holds the direction
  4983.      property it corresponds to (`n_to').
  4984.  
  4985. `s_obj'
  4986. `e_obj'
  4987. `w_obj'
  4988. `ne_obj'
  4989. `nw_obj'
  4990. `se_obj'
  4991. `sw_obj'
  4992.      Similar.
  4993.  
  4994. `u_obj'
  4995. `d_obj'
  4996. `in_obj'
  4997. `out_obj'
  4998.      Similar: the parser uses these if the player refers to `ceiling',
  4999.      `floor'.  (`in_obj' and `out_obj' differ slightly, because `in'
  5000.      and `out' are verbs with other effects in some cases.)
  5001.  
  5002. `thedark'
  5003.      A pseudo-room representing `being in darkness'.  `location' is then
  5004.      set to this room, but the player object is not moved to it.  Its
  5005.      `description' can be changed to whatever `It is dark here' message
  5006.      is desired.
  5007.  
  5008. `selfobj'
  5009.      The player object.  However, do not refer to `selfobj' directly:
  5010.      always refer to `player', a variable whose value is usually indeed
  5011.      `selfobj' but which might become `green_frog' if the player is
  5012.      transformed into one.
  5013.  
  5014.  
  5015.  
  5016. B.2 Library attributes
  5017. ======================
  5018.  
  5019. Here is a concise account of all the normal rules concerning all the
  5020. library's attributes.  (Except that: rules about how the parser sorts
  5021. out ambiguities are far too complicated to include here, but should not
  5022. concern designers anyway; and the definitions of `scope' and `darkness'
  5023. are given in the main text.)  Of course these rules are all modifiable
  5024. using suitable `before' and `after' rules.  But a good deal of
  5025. pragmatism has gone into their design, or rather evolution.
  5026.  
  5027. `absent'
  5028.      A `floating object' (one with a `found_in' property, which can
  5029.      appear in many different rooms) which is `absent' will no longer
  5030.      appear in the game.
  5031.  
  5032. `animate'
  5033.      `Is alive (human or animal)'.  Can be spoken to in `richard, hello'
  5034.      style; matches the `creature' token in grammar; picks up `him' or
  5035.      `her' (according to gender) rather than `it', likewise `his'; an
  5036.      object the player is changed into becomes `animate'; some messages
  5037.      read `on whom', etc., instead of `on which'; can't be taken; its
  5038.      subobjects `belong to' it rather than `are part of' it; messages
  5039.      don't assume it can be `touched' or `squeezed' as an ordinary
  5040.      object can; the actions `Attack', `ThrowAt' are diverted to `life'
  5041.      rather than rejected as being `futile violence'.
  5042.  
  5043. `clothing'
  5044.      Can be worn.
  5045.  
  5046. `concealed'
  5047.      `Concealed from view but present'.  The player's object has this;
  5048.      an object which was the player until `ChangePlayer' happened, loses
  5049.      this property; a `concealed' `door' can't be entered; does not
  5050.      appear in room descriptions.
  5051.  
  5052. `container'
  5053.      Affects scope (*note Scope::.) and light (*note Light::.); object
  5054.      lists recurse through it if `open' (or `transparent'); may be
  5055.      described as closed, open, locked, empty; a possession will give
  5056.      it a `LetGo' action if the player tries to remove it, or a
  5057.      `Receive' if something is put in; things can be taken or removed
  5058.      from it, or inserted into it, but only if it is `open'; likewise
  5059.      for `transfer' and `empty'; room descriptions describe using
  5060.      `when_open' or `when_closed' if given; if there is no defined
  5061.      `description', an `Examine' causes the contents to be searched
  5062.      (i.e., written out) rather than a message `You see nothing special
  5063.      about...'; `Search' only reveals the contents of `container's,
  5064.      otherwise saying `You find nothing'.
  5065.  
  5066. `direction'
  5067.      If the player tries to walk this way or enter it, a `Go' rather
  5068.      than `Enter' action is generated.  (Used only in one line of
  5069.      grammar, but a crucial one.)
  5070.  
  5071. `door'
  5072.      `Is a door or bridge'.  Room descriptions describe using
  5073.      `when_open' or `when_closed' if given; and an `Enter' action
  5074.      becomes a `Go' action.  If a `Go' has to go through this object,
  5075.      then: if `concealed', the player `can't go that way'; if not
  5076.      `open', then the player is told either that this cannot be
  5077.      ascended or descended (if the player tried `up' or `down' which
  5078.      went through it), or that it is in the way (otherwise); but if
  5079.      neither, then its `door_to' property is consulted to see where it
  5080.      leads; finally, if this is zero, then it is said to `lead nowhere'
  5081.      (a safety precaution) and otherwise the player actually moves to
  5082.      the location.
  5083.  
  5084. `edible'
  5085.      Can be eaten (and thus removed from game).
  5086.  
  5087. `enterable'
  5088.      Affects scope (*note Scope::.) and light (*note Light::.); only an
  5089.      `enterable' on the floor can be entered.
  5090.  
  5091. `female'
  5092.      Only applies to `animate's (and cannot have a `found_in' list for
  5093.      arcane reasons), and only affects the parser's use of pronouns: it
  5094.      says `her' is appropriate but `him' and `his' are not.
  5095.  
  5096. `general'
  5097.      A general-purpose attribute, defined by the library but never
  5098.      looked at or altered by it.  This is left free to mean something
  5099.      different for each object: often used by programmers for something
  5100.      like `the puzzle for this object has been solved'.
  5101.  
  5102. `light'
  5103.      `Is giving off light.'  *Note Light::.  Also: the parser
  5104.      understands `lit', `lighted', `unlit' using this; inventories will
  5105.      say `(providing light)' of it, and so will room descriptions if
  5106.      the current `location' is ordinarily dark; it will never be
  5107.      automatically put away into the player's `SACK_OBJECT' (as it
  5108.      might plausibly be inflammable or the main light source).
  5109.  
  5110. `lockable'
  5111.      Can be locked or unlocked by a player holding its key object,
  5112.      which is in the property `with_key'; if a `container' and also
  5113.      `locked', may be called `locked' in inventories.
  5114.  
  5115. `locked'
  5116.      Can't be opened.  If a `container' and also `locked', may be
  5117.      called `locked' in inventories.
  5118.  
  5119. `moved'
  5120.      `Has once been held by the player'.  Objects (immediately) owned
  5121.      by the player after `Initialise' has run are given it; at the end
  5122.      of each turn, if an item is newly held by the player and is
  5123.      `scored', it is given `moved' and `OBJECT_SCORE' points are
  5124.      awarded; an object's `initial' message only appears in room
  5125.      descriptions if it is unmoved.
  5126.  
  5127. `on'
  5128.      `Switched on.'  A `switchable' object with this is described by
  5129.      `with_on' in room descriptions; it will be called `switched on' by
  5130.      `Examine'.
  5131.  
  5132. `open'
  5133.      `Open door or container'.  Affects scope (*note Scope::.) and light
  5134.      (*note Light::.), and: lists (such as inventories) recurse through
  5135.      an `open' `container'; if a `container', called open by some
  5136.      descriptions; things can be taken or removed from an `open'
  5137.      `container'; similarly inserted, transferred or emptied.  An
  5138.      `open' `door' can be entered.  Described by `when_open' in room
  5139.      descriptions.
  5140.  
  5141. `openable'
  5142.      Can be opened or closed, unless `locked'.
  5143.  
  5144. `proper'
  5145.      Its short name is a proper noun, and never preceded by `the' or
  5146.      `The'.  The player's object must have this (so something changed
  5147.      into will be given it).
  5148.  
  5149. `scenery'
  5150.      Not listed (by the library) in room descriptions, `not portable'
  5151.      to be taken; `you are unable to' pull, push, or turn it.
  5152.  
  5153. `scored'
  5154.      The player gets `OBJECT_SCORE' points for picking it up for the
  5155.      first time; or, if a room, `ROOM_SCORE' points for visiting it for
  5156.      the first time.
  5157.  
  5158. `static'
  5159.      `Fixed in place' if player tries to take, remove, pull, push or
  5160.      turn.
  5161.  
  5162. `supporter'
  5163.      `Things can be put on top of it'.  Affects scope (*note Scope::.)
  5164.      and light (*note Light::.); object lists recurse through it; a
  5165.      possession will give it a `LetGo' action if the player tries to
  5166.      remove it, or a `Receive' if something is put in; things can be
  5167.      taken or removed from it, or put on it; likewise for transfers; a
  5168.      player inside it is said to be `on' rather than `in' it; room
  5169.      descriptions list its contents in separate paragraphs if it is
  5170.      itself listed.
  5171.  
  5172. `switchable'
  5173.      Can be switched on or off; listed as such by `Examine'; described
  5174.      using `when_on' or `when_off' in room descriptions.
  5175.  
  5176. `talkable'
  5177.      Player can talk to this object in `thing, do this' style.  (This is
  5178.      useful for microphones and the like.)
  5179.  
  5180. `transparent'
  5181.      Affects scope (*note Scope::.) and light (*note Light::.).  It
  5182.      roughly means `contents always visible'.  A `transparent'
  5183.      container is treated as if it were `open' for printing of contents.
  5184.  
  5185. `visited'
  5186.      Given to a room when a `Look' first happens there: if this room is
  5187.      `scored' then `ROOM_SCORE' points are awarded.  Affects whether
  5188.      room descriptions are abbreviated or not.
  5189.  
  5190. `workflag'
  5191.      Temporary flag used by Inform internals, also available to outside
  5192.      routines; can be used to select items for some lists printed by
  5193.      `WriteListFrom'.
  5194.  
  5195. `worn'
  5196.      `Item of clothing being worn'.  Should only be held by an object
  5197.      being immediately carried by player.  Affects inventories; doesn't
  5198.      count towards the limit of `MAX_CARRIED'; won't be automatically
  5199.      put away into the `SACK_OBJECT'; a `Drop' action will cause a
  5200.      `Disrobe' action first; so will `PutOn' or `Insert'; you can't
  5201.      insert or remove something from a `worn' container.
  5202.  
  5203. Note that very few attributes sensibly apply to rooms: only really
  5204. `light', `scored' and `visited', together with `general' if you choose
  5205. to use it.  Note also that an object cannot be both a `container' and a
  5206. `supporter'; and that the old attribute `autosearch', which was in
  5207. earlier releases, has been withdrawn as obselete.
  5208.  
  5209.  
  5210.  
  5211. B.3 Library properties
  5212. ======================
  5213.  
  5214. Next, definitions of properties which sensibly apply to `objects'
  5215. (meaning, things which are not rooms):
  5216.  
  5217. `after'
  5218.      List of rule routines to be applied in sequence after an action
  5219.      takes place.  (For a room, receives all actions in that room; for a
  5220.      player-object, all actions by the player as that object.)
  5221.  
  5222. `article'
  5223.      Indefinite article for object (defaults to `a').
  5224.  
  5225. `before'
  5226.      List of rule routines to be applied in sequence before an action
  5227.      takes place.  (For a room, receives all actions in that room; for a
  5228.      player-object, all actions by the player as that object.)
  5229.  
  5230. `cant_go'
  5231.      Message to print (or routine to print one) when a player tries to
  5232.      go in an impossible direction from this room (defaults to `You
  5233.      can't go that way.')
  5234.  
  5235. `capacity'
  5236.      Number of objects a `container' or `supporter' can hold (defaults
  5237.      to 100); number of things the player can carry (when the player is
  5238.      this object), initially set to `MAX_CARRIED' for the standard
  5239.      player object.
  5240.  
  5241. `daemon'
  5242.      Routine to run each turn (once activated by a `StartDaemon' and
  5243.      until stopped by a `StopDaemon').  Note: the same object cannot
  5244.      have both a `daemon' and a `time_out'.
  5245.  
  5246. `describe'
  5247.      Routine (only) to describe object: over-rides a room's
  5248.      `description' to give main room description, if set; over-rides an
  5249.      object's usual listing when it appears in a room description.
  5250.  
  5251. `description'
  5252.      `Examine' message, or routine to print one out, for an object; main
  5253.      room description, or routine to print one, for a room.
  5254.  
  5255. `door_dir'
  5256.      Direction (that is, direction property, such as `n_to', not
  5257.      direction object) that a `door' goes via, or a routine which
  5258.      returns this information; also used for direction objects.  *Note
  5259.      Compass: Library objects.
  5260.  
  5261. `door_to'
  5262.      Room that a `door' connects to, or routine returning this; a value
  5263.      of 0 means `leads nowhere' (but this is not the ideal way to
  5264.      implement such a door).
  5265.  
  5266. `each_turn'
  5267.      String to print, or list of routines to run, each turn that the
  5268.      object is in scope, after all timers and daemons have run.
  5269.  
  5270. `found_in'
  5271.      List of rooms in which a `floating object' (that is, one present in
  5272.      multiple rooms) is found, unless it has `absent', in which case it
  5273.      is nowhere to be found.
  5274.  
  5275. `initial'
  5276.      Initial description of object not yet picked up, or routine to
  5277.      print one.
  5278.  
  5279. `invent'
  5280.      Routine to change its inventory listing.  *Note Inventories::.
  5281.  
  5282. `life'
  5283.      List of rule routines to be applied in sequence after an action
  5284.      making sense for an `animate' object takes place.
  5285.  
  5286. `name'
  5287.      List of dictionary words referring to an object (note: uniquely,
  5288.      these dictionary words are given in double quotes `"thus"',
  5289.      whereas in all other circumstances they would be `'thus''; part
  5290.      tradition, part defence against `'a'' single-letter ambiguity).
  5291.      For a room, lists dictionary words which `do not need to be
  5292.      referred to in this game'.
  5293.  
  5294. `number'
  5295.      A general purpose property left free: conventionally holding a
  5296.      number like `number of turns' battery power left'.  (Except: an
  5297.      object to be used as a player-object must provide one, and it
  5298.      isn't left free.)
  5299.  
  5300. `parse_name'
  5301.      Routine (only) to parse object's name (this overrides the `name'
  5302.      and is also used in determining if two objects are describably
  5303.      identical).  *Note Naming of names::.
  5304.  
  5305. `plural'
  5306.      The plural name of an object (when in the presence of others like
  5307.      it), or routine to print it.
  5308.  
  5309. `short_name'
  5310.      The short name of an object (like `brass lamp'), or routine to
  5311.      print it.
  5312.  
  5313. `time_left'
  5314.      Number of turns left until timer (if set, which must be done using
  5315.      `StartTimer') goes off.
  5316.  
  5317. `time_out'
  5318.      Routine to run when timer goes off (having been set by `StartTimer'
  5319.      and not in the mean time stopped by `StopTimer').  Note: the same
  5320.      object cannot have both a `daemon' and a `time_out'.
  5321.  
  5322. `when_closed'
  5323.      `Look' description of something closed (`door' or `container'), or
  5324.      routine to print one.
  5325.  
  5326. `when_open'
  5327.      `Look' description of something open (`door' or `container'), or
  5328.      routine to print one.
  5329.  
  5330. `when_off'
  5331.      `Look' description of a `switchable' which isn't `on', or routine
  5332.      to print one.
  5333.  
  5334. `when_on'
  5335.      `Look' description of a `switchable' which is `on', or routine to
  5336.      print one.
  5337.  
  5338. `with_key'
  5339.      Key object needed to lock/unlock a `lockable' object; player must
  5340.      explicitly name it as the key being used and be holding it at the
  5341.      time to use it.  May be 0, in which case no key fits.
  5342.  
  5343. together with the properties
  5344.  
  5345.      n_to   s_to    ne_to   se_to    u_to    d_to
  5346.      e_to   w_to    nw_to   sw_to    in_to   out_to
  5347.  
  5348. each of which can be map connections to other routines, or strings (in
  5349. which case they are printed if the player tries to go that way, but the
  5350. move is not allowed and no further action is taken), or routines (in
  5351. which case they are called to decide whether the map connection exists
  5352. or not, and if so where it leads).
  5353.  
  5354. *WARNING:* Do not confuse `n_to' and so on with the 12 direction
  5355. objects, `n_obj' et al.
  5356.  
  5357.  
  5358.  
  5359.  
  5360. C All the entry points, library routines and constants
  5361. ******************************************************
  5362.  
  5363.  
  5364.  
  5365. C.1 Library entry points
  5366. ========================
  5367.  
  5368. Entry points are routines which you can provide, if you choose to, and
  5369. which are called by the library routines to give you the option of
  5370. changing the rules.  All games *must* define an `Initialise' routine,
  5371. which is obliged to set the `location' variable to a room; the rest are
  5372. optional.
  5373.  
  5374. `AfterLife'
  5375.      When the player has died (a condition signalled by the variable
  5376.      `deadflag' being set to a non-zero value other than 2, which
  5377.      indicates winning), this routine is called: by setting `deadflag=0'
  5378.      again it can resurrect the player.
  5379.  
  5380. `Amusing'
  5381.      Called to provide an `afterword' for players who have won (for
  5382.      instance, it might advertise some features which a successful
  5383.      player might never have noticed).  (But only if you have defined
  5384.      the constant `AMUSING_PROVIDED' in your own code.)
  5385.  
  5386. `DarkToDark'
  5387.      Called when a player goes from one dark room into another one; a
  5388.      good excuse to kill the player off in anyone's book.
  5389.  
  5390. `DeathMessage'
  5391.      Prints up `You have died' style messages, for `deadflag' values of
  5392.      3 or more.  (If you choose ever to set `deadflag' to such.)
  5393.  
  5394. `GamePostRoutine'
  5395.      A kind of super-`after' rule, which applies to all actions in the
  5396.      game, whatever they are: use only in the last resort.
  5397.  
  5398. `GamePreRoutine'
  5399.      A kind of super-`before' rule, which applies to all actions in the
  5400.      game, whatever they are: use only in the last resort.
  5401.  
  5402. `Initialise'
  5403.      A compulsory routine, which must set `location' and is convenient
  5404.      for miscellaneous initialising, perhaps for random settings.
  5405.  
  5406. `InScope'
  5407.      An opportunity to place extra items in scope during parsing, or to
  5408.      change the scope altogether.  (If `et_flag' is 1 when this is
  5409.      called, the scope is being worked out for `each_turn' reasons;
  5410.      otherwise for everyday parsing.)
  5411.  
  5412. `LookRoutine'
  5413.      Called at the end of every `Look' description.
  5414.  
  5415. `NewRoom'
  5416.      Called when the room changes, before any description of it is
  5417.      printed.  (This happens no matter how the change of room occurred.)
  5418.  
  5419. `ParseNumber'
  5420.      An opportunity to parse numbers in a different (or additional) way.
  5421.  
  5422. `ParserError'
  5423.      The chance to print different parser error messages (like `I don't
  5424.      understand that sentence').
  5425.  
  5426. `PrintRank'
  5427.      Completes the printing of the score.  (You might want to change
  5428.      this, so as to make the ranks something like `junior astronaut' or
  5429.      `master catburglar' or whatever suits your game.)
  5430.  
  5431. `PrintVerb'
  5432.      A chance to change the verb printed out in a parser question (like
  5433.      `What do you want to (whatever)?') in case an unusual verb via
  5434.      `UnknownVerb' has been constructed.  Returns true (or 1) if it has
  5435.      printed something.
  5436.  
  5437. `PrintTaskName'
  5438.      Prints the name of a game task (such as `driving the car').
  5439.  
  5440. `TimePasses'
  5441.      Called after every turn (but not, for instance, after a command
  5442.      like `score' or `save').  It's much more elegant to use timers and
  5443.      daemons, or `each_turn' routines for individual rooms - using this
  5444.      is a last resort.
  5445.  
  5446. `UnknownVerb'
  5447.      Called by the parser when it hits an unknown verb, so that you can
  5448.      transform it into a known one.
  5449.  
  5450.  
  5451.  
  5452. C.2 Library routines
  5453. ====================
  5454.  
  5455. Library routines which are `open to the public':
  5456.  
  5457. `Achieved(task)'
  5458.      Indicate the `task' is achieved (which only awards score the first
  5459.      time).
  5460.  
  5461. `AllowPushDir()'
  5462.      Signal that an attempt to push an object from one place to another
  5463.      should be allowed.
  5464.  
  5465. `CDefArt(object)'
  5466.      Print the capitalised definite article and short name of `object'.
  5467.  
  5468. `ChangePlayer(object, flag)'
  5469.      Cause the player at the keyboard to play as the given object,
  5470.      which must have a `number' property supplied.  If the `flag' is
  5471.      set to 1, then subsequently print messages like `(as Ford
  5472.      Prefect)' in room description headers.  This routine, however,
  5473.      prints nothing itself.
  5474.  
  5475. `DefArt(object)'
  5476.      Print the definite article and short name of `object'.
  5477.  
  5478. `DoMenu(text,routine,routine)'
  5479.      Produce a menu.
  5480.  
  5481. `EnglishNumber(x)'
  5482.      Prints out `x' in English (e.g., `two hundred and seventy-seven').
  5483.  
  5484. `HasLightSource(object)'
  5485.      Returns true if `object' `has light'.
  5486.  
  5487. `InDefArt(object)'
  5488.      Print the indefinite article and short name of `object'.
  5489.  
  5490. `NextWord()'
  5491.      Returns the next dictionary word in the player's input, moving the
  5492.      word number `wn' on by one.  Returns -1 if the player's input has
  5493.      run out, and 0 if the word is not in the dictionary.
  5494.  
  5495. `OffersLight(object)'
  5496.      Returns true if `object' `offers light'.
  5497.  
  5498. `PlaceInScope(object)'
  5499.      Puts `object' into scope for the parser.
  5500.  
  5501. `PlayerTo(place, flag)'
  5502.      Move the player to `place'.  Unless `flag' is given and is 1,
  5503.      describe the player's surroundings.
  5504.  
  5505. `PrintShortName(object)'
  5506.      Print the short name of `object'.  (This is protected against
  5507.      `object' having a meaningless value.)
  5508.  
  5509. `ScopeWithin(object)'
  5510.      Puts the contents of `object' into scope, recursing downward
  5511.      according to the usual scope rules.
  5512.  
  5513. `SetTime(time,rate)'
  5514.      Set the game clock (a 24-hour clock) to the given `time' (in
  5515.      seconds since the start of the day), to run at the given rate
  5516.      RATE: 0 means it does not run; if RATE > 0 then RATE seconds pass
  5517.      every turn; if RATE < 0 then -RATE turns pass every second.
  5518.  
  5519. `ScopeWithin(object)'
  5520.      Puts the contents of `object', recursing downward according to the
  5521.      usual scope rules.
  5522.  
  5523. `StartDaemon(object)'
  5524.      Makes the daemon of `object' active, so that its `daemon' routine
  5525.      will be called every turn.
  5526.  
  5527. `StartTimer(object, time)'
  5528.      Starts the timer of `object', set to go off in `time' turns, at
  5529.      which time its `time_out' routine will be called (it must provide
  5530.      a `time_left' property).
  5531.  
  5532. `StopDaemon(object)'
  5533.      Makes the daemon of `object' inactive, so that its `daemon'
  5534.      routine is no longer called.
  5535.  
  5536. `StopTimer(object)'
  5537.      Stops the timer of `object', so that it won't go off after all.
  5538.  
  5539. `TryNumber(wordnum)'
  5540.      Tries to parse the word at `wordnum' as a number (recognising
  5541.      decimal numbers and English ones from `one' to `twenty'), returning
  5542.      -1000 if it fails altogether, or the number.  Values exceeding
  5543.      10000 are rounded down to 10000.
  5544.  
  5545. `WriteListFrom(object, style)'
  5546.      Write a list of `object' and its siblings, with `style' a bitmap
  5547.      of options.
  5548.  
  5549. `YesOrNo()'
  5550.      Assuming that a question has already been printed, wait for the
  5551.      player to type `yes' or `no', returning true or false accordingly.
  5552.  
  5553.  
  5554.  
  5555. C.3 Library constants
  5556. =====================
  5557.  
  5558. And, finally, the constants:
  5559.  
  5560. `AMUSING_PROVIDED'
  5561.      To indicate that an `Amusing' routine is provided.
  5562.  
  5563. `DEBUG'
  5564.      To include the special `debugging' verbs.
  5565.  
  5566. `Headline'
  5567.      Style of game and copyright message.
  5568.  
  5569. `MAX_CARRIED'
  5570.      Maximum number of (direct) possessions the player can carry.
  5571.  
  5572. `MAX_SCORE'
  5573.      Maximum game score.
  5574.  
  5575. `MAX_TIMERS'
  5576.      Maximum number of timers or daemons active at any one time
  5577.      (defaults to 32).
  5578.  
  5579. `NUMBER_TASKS'
  5580.      Number of `tasks' to perform.
  5581.  
  5582. `OBJECT_SCORE'
  5583.      Score for picking up a `scored' object for the first time.
  5584.  
  5585. `ROOM_SCORE'
  5586.      Score for visiting up a `scored' room for the first time.
  5587.  
  5588. `SACK_OBJECT'
  5589.      Object which acts as a `rucksack', into which the game
  5590.      automatically tidies away things for the player.
  5591.  
  5592. `Story'
  5593.      Story name, conventionally in CAPITAL LETTERS.
  5594.  
  5595. `TASKS_PROVIDED'
  5596.      To indicate that `tasks' are provided.
  5597.  
  5598.  
  5599.  
  5600.  
  5601. D All the Inform error messages
  5602. *******************************
  5603.  
  5604. Inform can produce about 230 different error messages.  The error
  5605. messages were tidied-up and made more consistent in Inform 5.4, which
  5606. the text here comes from, but earlier editions were similar.  Since
  5607. interpreters can in some cases crash horribly when given incorrect
  5608. files, Inform never writes a file which caused an error, though it will
  5609. permit files which incurred only warnings.
  5610.  
  5611.  
  5612.  
  5613. D.1 Fatal errors
  5614. ================
  5615.  
  5616. To begin with, fatal errors (which stop Inform in its tracks) come in
  5617. three kinds, the first containing only this one:
  5618.  
  5619.      Too many errors: giving up
  5620.  
  5621. After 100 errors, Inform stops (in case it has been given the wrong
  5622. source file altogether).  Secondly, file input/output can go wrong.
  5623. Most commonly, Inform has the wrong filename:
  5624.  
  5625.      Couldn't open input file <filename>
  5626.      Couldn't open output file <filename>
  5627.      Couldn't open transcript file <filename>
  5628.      Couldn't open debugging information file <filename>
  5629.      Couldn't open temporary file 1 <filename>
  5630.      Couldn't open temporary file 2 <filename>
  5631.      Too many files have included each other: increase #define MAX_INCLUSION_DEPTH
  5632.  
  5633. (Temporary files are used (on most machines) for temporary storage space
  5634. during compilation.  They are removed afterwards.)  The last error only
  5635. occurs if 5 files all include each other.  Increasing this `#define'
  5636. means re-compiling Inform from its C source, a drastic measure.  The
  5637. remaining file-handling errors usually mean that the disc is full:
  5638. something has gone wrong with an already-open file.
  5639.  
  5640.      I/O failure: couldn't read from source file
  5641.      I/O failure: couldn't write to temporary file 1
  5642.      I/O failure: couldn't reopen temporary file 1
  5643.      I/O failure: couldn't read from temporary file 1
  5644.      I/O failure: couldn't write to temporary file 2
  5645.      I/O failure: couldn't reopen temporary file 2
  5646.      I/O failure: couldn't read from temporary file 2
  5647.      I/O failure: couldn't write to story file
  5648.      I/O failure: couldn't write to transcript file
  5649.      I/O failure: can't write to debugging information file
  5650.  
  5651. The third class of fatal error is Inform running out of memory.  It
  5652. might fail drastically, having not enough memory to get started, as
  5653. follows...
  5654.  
  5655.      Couldn't allocate memory
  5656.      Couldn't allocate memory for an array
  5657.  
  5658. (There are four similar `hallocate' errors unique to the PC `Quick C'
  5659. port.)  More often it will run out in the course of compilation, like
  5660. so:
  5661.  
  5662.      The memory setting <setting> (which is <value> at present)
  5663.          has been exceeded.
  5664.      Try running Inform again with $<setting>=<some-larger-number>
  5665.          on the command line.
  5666.  
  5667. For details of the memory settings, *Note Memory settings::.
  5668.  
  5669.  
  5670.  
  5671. D.2 Errors
  5672. ==========
  5673.  
  5674. There are a few conventions.  Anything in double-quotes is a display
  5675. from your source code; other strings are in single-quotes.  A message
  5676. like
  5677.  
  5678.      Expected ... but found "..."
  5679.  
  5680. means that Inform expected something different from what it found; if it
  5681. doesn't say what it found, this usually means it found nothing (i.e.,
  5682. the statement was incomplete).  Messages in the form
  5683.  
  5684.      No such ... as "..."
  5685.      Not a ...: "..."
  5686.  
  5687. mean that a name is unrecognised in the former case (say, a typing error
  5688. might produce this), or is recognised but means something else in the
  5689. latter case (an attempt to use a routine where a property is expected
  5690. would give such an error).
  5691.  
  5692. To begin with, the source-code format may go awry:
  5693.  
  5694.      Too many tokens on line (note: to increase the maximum, set
  5695.          $MAX_TOKENS=some-bigger-number on the Inform command line)
  5696.      Line too long (note: to increase the maximum length, set
  5697.          $BUFFER_LENGTH=some-bigger-number on the Inform command line)
  5698.      Too much text for one pair of "s to hold
  5699.      Too much text for one pair of 's to hold
  5700.      Open quotes " expected for text but found <text>
  5701.      Close quotes " expected for text but found <text>
  5702.  
  5703. (Usually `BUFFER_LENGTH' allows about 2000 characters per line.) When
  5704. giving something (such as an object) an internal name, there are rules
  5705. to be obeyed; for instance, you can't give an object the same name as a
  5706. property already declared:
  5707.  
  5708.      Symbol name expected
  5709.      Symbol names are not permitted to start with an '_'
  5710.      Symbol name is too long: <text>
  5711.      Duplicated symbol name: <text>
  5712.  
  5713. At the top level, the most common `no such command' error is
  5714.  
  5715.      Expected an assignment, command, directive or opcode but found <text>
  5716.  
  5717. which means Inform didn't even understand the first word of the command.
  5718. Directives to Inform can produce the following errors:
  5719.  
  5720.      All 32 attributes already declared (compile as Advanced game to
  5721.          get an extra 16)
  5722.      All 48 attributes already declared
  5723.      All 30 properties already declared (compile as Advanced game to
  5724.          get an extra 32)
  5725.      All 62 properties already declared
  5726.      Expected an attribute name after 'alias'
  5727.      Expected a property name after 'alias'
  5728.      'alias' incompatible with 'long'
  5729.      'alias' incompatible with 'additive'
  5730.      'alias' refers to undefined attribute <text>
  5731.      'alias' refers to undefined property <text>
  5732.      All 235 global variables already declared
  5733.      Expected 'string', 'data', 'initial', 'initstr' or '=' but found <text>
  5734.  
  5735. Use of `alias' is rare (except inside the library files).  The last of
  5736. these errors means that a global variable has been wrongly initialised,
  5737. and a common cause of this is typing, say, `global trolls 5;' instead
  5738. of `global trolls = 5;'.
  5739.  
  5740.      '*' divider expected, but found <text>
  5741.      No such token as <text>
  5742.      Expected '=' after 'scope' but found <text>
  5743.      Expected routine after 'scope=' but found <text>
  5744.      Expected routine after 'noun=' but found <text>
  5745.      '=' is only legal here as 'noun=Routine'
  5746.      '->' clause missing
  5747.      No such action routine as <text>
  5748.      Not an action: <text>
  5749.      Too many lines of grammar for verb: increase #define MAX_LINES_PER_VERB
  5750.      There is no previous grammar for the verb <text>
  5751.      Two different verb definitions refer to <text>
  5752.      Expected 'replace', 'last' or 'first' but found <text>
  5753.  
  5754. These are the grammatical errors, the last three concerning `extend'ed
  5755. verb definitions.  Normally one gets 16 grammar lines per verb.  It's
  5756. probably better to write grammar more carefully (using routines to
  5757. parse adjectives more carefully, for instance) than to exceed this, as
  5758. the game parser will otherwise slow down.  The object/class definition
  5759. errors are largely self-explanatory:
  5760.  
  5761.      Object/class definition finishes with ','
  5762.      Two commas ',' in a row in object/class definition
  5763.      No such attribute as <text>
  5764.      No such class as <text>
  5765.      Expected 'with', 'has' or 'class' in object/class definition but found <text>
  5766.      Expected an (internal) name for object but found the string <text>
  5767.      An object must be defined after the one which contains it: (so far)
  5768.          there is no such object as <text>
  5769.      Not an object: <text>
  5770.      No such property as <text>
  5771.      Not a property: <text>
  5772.  
  5773. Miscellaneous errors complete the list produced by mostly-uncommon
  5774. directives:
  5775.  
  5776.      Expected ';' after 'include <file>' but found <text>
  5777.      A 'switches' directive must come before constant definitions
  5778.      Expected 'score' or 'time' after 'statusline' but found <text>
  5779.      The serial number must be a 6-digit date in double-quotes
  5780.      The version number must be 3 to 6: 3 for Standard games and 5 for Advanced
  5781.      Expected 'on' or 'off' after 'font' but found <text>
  5782.      Defaulted constants can't be strings
  5783.      Must specify 0 to 3 variables in 'stub' routine
  5784.      Expected 'full' or nothing after 'etrace' but found <text>
  5785.      Too many abbreviations declared
  5786.      All abbreviations must be declared together
  5787.      It's not worth abbreviating <text>
  5788.      Expected a 'string' value
  5789.      No such directive as <text>
  5790.  
  5791. Conditional compilation happens as a result of one of `#IFDEF', `#IFV3'
  5792. or `#IFV5'.  (The former tests whether a constant is defined; the
  5793. latter test for version-3 (Standard) games or version-5 (Advanced)
  5794. games.)  An `#IFNOT' section is optional but the closing `#ENDIF' is
  5795. compulsory.  In these error messages `#IF...' means any of the three
  5796. opening clauses.
  5797.  
  5798.      '#IF...' nested too deeply: increase #define MAX_IFDEF_DEPTH
  5799.      '#ENDIF' without matching '#IF...'
  5800.      '#IFNOT' without matching '#IF...'
  5801.      Two '#IFNOT's in the same '#IF...'
  5802.      End of file reached inside '#IF...'
  5803.  
  5804. Routines begin with a `[' and some local variables and end with `]':
  5805.  
  5806.      Routine has more than 15 local variables
  5807.      The earliest-defined routine is not allowed to have local variables
  5808.      Expected local variable but found ',' or ':' (probably the ';' after the
  5809.          '[ ...' line was forgotten)
  5810.      Misplaced ']'
  5811.      Comma ',' after ']' can only be used inside object/class definitions
  5812.      Expected ',' or ';' after ']' but found <text>
  5813.      Expected ';' after ']' but found <text>
  5814.  
  5815. The error messages for expressions are fairly simple.  Note, however,
  5816. that one is not allowed to type, say, `lamp.number++;' but must instead
  5817. write `lamp.number = lamp.number + 1;' (the `++' and `--' operators can
  5818. only be applied to variables, not properties).
  5819.  
  5820.      Expected condition but found expression
  5821.      Unexpected condition
  5822.      Expected an assignment but found <text>
  5823.      Expected an assignment but found an expression
  5824.      Attempt to use void as a value
  5825.      Attempt to use an assignment as a value
  5826.      Attempt to use a condition as a value
  5827.      Operator has too few arguments
  5828.      Operator has too many arguments
  5829.      '++' and '--' can only apply directly to variables
  5830.      At most three values can be separated by 'or'
  5831.      'or' can only be used with the conditions '==' and '~='
  5832.      Too many brackets '(' in expression
  5833.      Brackets '(' too deeply nested
  5834.      Missing bracket ')' in function call
  5835.      Spurious comma ','
  5836.      Misplaced comma ','
  5837.      Wrong number of arguments to system function
  5838.      'children' takes a single argument
  5839.      'youngest' takes a single argument
  5840.      'elder' takes a single argument
  5841.      'indirect' takes at least one argument
  5842.      Type mismatch in argument <text>
  5843.      A function may be called with at most 3 arguments
  5844.      Malformed statement 'Function(...);'
  5845.      Spurious terms after function call
  5846.      Spurious terms after assignment
  5847.      Spurious terms after expression
  5848.  
  5849. Next, constants.  Note that dictionary words cannot start with a
  5850. non-alphabetic character, which means that Infocom-style `debugging
  5851. verbs' which traditionally begin with a `#' are not allowed.
  5852.  
  5853.      No such variable as <text>
  5854.      No such constant as <text>
  5855.      Not a constant: <text>
  5856.      Reserved word as constant: <text>
  5857.      No such routine as <text>
  5858.      Dictionary words must begin with a letter of the alphabet
  5859.      Dictionary word not found for constant <text>
  5860.  
  5861. Loop constructs: note that `old-style' `for' loops are a rather
  5862. obselete form (e.g., `for i 1 to 10'), and the more flexible style `for
  5863. (i=1:i<=10:i++)' is now preferred.
  5864.  
  5865.      'if' statement with more than one 'else'
  5866.      'else' attached to a loop block
  5867.      'for' loops too deeply nested
  5868.      ':' expected in 'for' loop
  5869.      Second ':' expected in 'for' loop
  5870.      Concluding ')' expected in 'for' loop
  5871.      'to' missing in old-style 'for' loop
  5872.      'to' expected in old-style 'for' loop
  5873.      Final value missing in old-style 'for' loop
  5874.      '{' required after an old-style 'for' loop
  5875.      Old-style 'for' loops must have simple final values
  5876.      Open bracket '(' expected in 'objectloop'
  5877.      'objectloop' must be 'from', 'near' or 'in' something
  5878.      Close bracket ')' expected in 'objectloop'
  5879.      Braces '{' are compulsory unless the condition is bracketed
  5880.      Unmatched '}' found
  5881.      Brace mismatch in previous routine
  5882.  
  5883. Inform checks the level of braces when a routine closes so that it can
  5884. recover as quickly as possible from a mismatch; this last error means at
  5885. least one brace is still open when the routine finishes.
  5886.  
  5887.      The object to 'give' to must be a variable or constant
  5888.      Expected some attributes to 'give'
  5889.      Expected 'to <object>' in 'move'
  5890.      Expected 'to' in 'move' but found <text>
  5891.      Expected ',' in 'print' list but found <text>
  5892.      Expected 'style' to be 'roman', 'bold', 'underline' or 'reverse'
  5893.          but found <text>
  5894.      Expected a parse buffer for 'read'
  5895.      Expected some properties to 'write'
  5896.      The object to 'write' must be a variable or constant
  5897.      Expected property value to 'write'
  5898.      Expected 'byte' or 'word' in 'put'
  5899.      Expected 'byte' or 'word' in 'put' but found <text>
  5900.  
  5901. These are miscellaneous commands and `put' and `write' are quite
  5902. obselete.  Only action commands like `<Take brass_lantern>' remain:
  5903.  
  5904.      Action name too long or a string: perhaps a statement accidentally ended
  5905.          with a comma?
  5906.      Action commands must take the form '< Action ... >'
  5907.      The longest action command allowed is '<Action noun second>'
  5908.      Angle brackets do not match
  5909.      Action given in constant does not exist
  5910.      Action name over 60 characters long: <text>
  5911.      Expected ':' (after action) but found <text>
  5912.  
  5913. The first of these may be caused by something like:
  5914.  
  5915.          "You load the crossbow bolt.",
  5916.       Drop:  "The bolt falls to the floor with a thump.";
  5917.  
  5918. where a comma has been typed instead of a semicolon after the first
  5919. string, so that Inform thinks you are giving a rule for two actions, one
  5920. being `Drop' and the other apparently called `"You load the crossbow
  5921. bolt."'.
  5922.  
  5923.  
  5924.  
  5925. D.3 Internal and assembler errors
  5926. =================================
  5927.  
  5928. By now we have descended to the ninth circle of Inform: the assembler.
  5929. These errors are fairly unmysterious (if only because they seldom
  5930. happen), but sometimes one is told something odd like
  5931.  
  5932.      No such label as _f456
  5933.  
  5934. which is caused by Inform failing to recover properly from a previous
  5935. brace mismatch error.  Just ignore this and fix the earlier error (which
  5936. will also have been reported).  The `no such variable' error is
  5937. occasionally seen when an unknown variable is first referred to by being
  5938. written to.
  5939.  
  5940.      No such assembly opcode as <text>
  5941.      Too many arguments
  5942.      Can't store to that (no such variable)
  5943.      Branch too far forward: use '?'
  5944.      No such return condition for branch
  5945.      Can't branch to a routine, only to a label
  5946.      No such label as <text>
  5947.      Not a label: <text>
  5948.  
  5949. To conclude with, there are a few internal error messages:
  5950.  
  5951.      A label has moved between passes because of a low-level error just before
  5952.          (perhaps an improper use of a routine address as a constant)
  5953.      Object has altered in memory usage between passes: perhaps an attempt to
  5954.          use a routine name as value of a small property
  5955.      Duplicated system symbol name <text>
  5956.      Internal error - unknown directive code
  5957.      Internal error - unknown compiler code
  5958.  
  5959. The last three should not happen.  The first two occasionally do, and
  5960. cause some confusion.  Inform performs two tests regularly as a
  5961. safeguard to make sure that code has not come out substantially
  5962. different in its two passes.  The first failure occurs in code, the
  5963. second for object/class definitions.  Whatever caused this should be
  5964. something unusual, low-level and just before the error occurred: if you
  5965. get these errors with innocent high-level code, then probably Inform
  5966. should provide a suitable error message, so please email the author with
  5967. a sample of offending code.
  5968.  
  5969.  
  5970.  
  5971. D.4 Warnings
  5972. ============
  5973.  
  5974. Inform can produce any number of warnings without shutting down.  Note
  5975. that Inform tries to give only warnings when it hits Advanced-game
  5976. features in what is to be a Standard game, for the sake of portability.
  5977. Nevertheless it is probably better to use `#IFV3' and `#IFV5' clauses
  5978. around any pieces of code which are to be different in these two
  5979. versions (if, indeed, you want two different versions).
  5980.  
  5981.      Local variable unused: <text>
  5982.      Since it is defined before inclusion of the library, game-play will begin
  5983.          not at 'Main' but at the routine <text>
  5984.      Ignoring Advanced-game status routine
  5985.      Ignoring this Advanced-game command
  5986.      Missing ','?  Property data seems to contain the property name <text>
  5987.      Standard-game limit of 8 bytes per property exceeded (use Advanced to get
  5988.          64), so truncating property <text>
  5989.      Ignoring Advanced-game opcode <text>
  5990.      Ignoring Standard-game opcode <text>
  5991.  
  5992.  
  5993.  
  5994.  
  5995. E Compiler options and memory settings
  5996. **************************************
  5997.  
  5998.      I was promised a horse, but what I got instead
  5999.      was a tail, with a horse hung from it almost dead.
  6000.      
  6001.      -- Palladas of Alexandria, translated by Tony Harrison
  6002.  
  6003. *The reader is warned that some details in this section are slightly
  6004. different on different machines.*
  6005.  
  6006.  
  6007.  
  6008. E.1 Compiler options
  6009. ====================
  6010.  
  6011. On most machines, Inform is run from the command line, by a command like
  6012.  
  6013.      inform -xv5 balances
  6014.  
  6015. and simply typing `inform' will produce a good deal of help information
  6016. about the command line options available.  The command line syntax is
  6017.  
  6018.      `inform' SWITCHES SETTINGS SOURCE FILE OUTPUT FILE
  6019.  
  6020. where only the SOURCE FILE is mandatory.  (By default, the full names
  6021. to give the source and output files are derived in a way suitable for
  6022. the machine Inform is running on: on a PC, for instance, `advent' may
  6023. be understood as asking to compile `advent.inf' to `advent.z5'.)
  6024.  
  6025. The switches are given in one or more groups, preceded by a minus sign
  6026. `-' in the usual Unix command-line style.  The current list of legal
  6027. switches is:
  6028.  
  6029.        a   list assembly-level instructions compiled
  6030.        b   give statistics and/or line/object list in both passes
  6031.        c   more concise error messages
  6032.        d   contract double spaces after full stops in text
  6033.        e   economy mode (slower): make use of declared abbreviations
  6034.        f   frequencies mode: show how useful abbreviations are
  6035.        g   with debugging code: traces all function calls
  6036.        h   print this information
  6037.        i   ignore default switches set within the file
  6038.        j   list objects as constructed
  6039.        k   output Infix debugging information to "Game_Debug"
  6040.        l   list all assembly lines
  6041.        m   say how much memory has been allocated
  6042.        n   print numbers of properties and attributes
  6043.        o   print offset addresses
  6044.        p   give percentage breakdown of story file
  6045.        r   record all the text to "Game_Text"
  6046.        s   give statistics
  6047.        t   trace Z-code assembly
  6048.        u   work out most useful abbreviations
  6049.        v3  compile to version-3 (Standard) story file
  6050.        v4  compile to version-4 (Plus) story file
  6051.        v5  compile to version-5 (Advanced) story file
  6052.        v6  compile to version-6 (graphical) story file
  6053.        w   disable warning messages
  6054.        x   print # for every 100 lines compiled (in both passes)
  6055.        z   print memory map of the Z-machine
  6056.        T   enable throwback of errors in the DDE
  6057.  
  6058. (Thus, as long as your name doesn't have a `q' or `y' in it, you can
  6059. amuse yourself typing your name in as a switch and see what it does.)
  6060. Note that these switches can also be selected by putting a `switches'
  6061. directive into the source code before anything else, such as
  6062.  
  6063.          Switches xdv5s;
  6064.  
  6065. The most useful switches are `v3' and `v5', which choose between
  6066. Standard and Advanced games.  For example, the above line is from the
  6067. example game `Advent', which is consequently compiled to an Advanced
  6068. game.  (If no choice is stated, a Standard game results.) The options
  6069. `v4' and `v6' are provided for completeness but their use is not
  6070. recommended.
  6071.  
  6072. Many of the remaining switches make Inform produce extra output, but do
  6073. not affect its compilation:
  6074.  
  6075. `a b l m n t'
  6076.      are tracing options to help with maintaining Inform, or for
  6077.      debugging assembly language programs
  6078.  
  6079. `o p s z'
  6080.      will print out information about the final game file, the `s'
  6081.      (statistics) option being particularly useful to keep track of how
  6082.      large the game is growing
  6083.  
  6084. `c w T'
  6085.      in `c' mode, Inform does not quote whole source lines together with
  6086.      error messages; in `w' mode it suppresses warnings; in `T' mode,
  6087.      which is only present on the Acorn Archimedes, error throwback
  6088.      will occur in the `Desktop Development Environment'
  6089.  
  6090. `f'
  6091.      indicates roughly how many bytes the abbreviations saved
  6092.  
  6093. `h'
  6094.      prints out the help information (and is equivalent to just typing
  6095.      `inform')
  6096.  
  6097. `j x'
  6098.      make Inform print out steady text to prove that it's still awake:
  6099.      on very slow machines this may be a convenience
  6100.  
  6101. `k'
  6102.      writes a `debugging information' file for the use of the Infix
  6103.      debugger (similarly, the filename is something suitable for the
  6104.      machine)
  6105.  
  6106. `r'
  6107.      is intended to help with proof-reading the text of a game, and
  6108.      transcribes all of the text in double-quotes to the given file
  6109.      (whose name is something suitable for the machine)
  6110.  
  6111. `u'
  6112.      will try to work out a good set of abbreviations to declare for
  6113.      your game, but *extremely slowly* (a matter of hours) and
  6114.      *consuming very much memory* (perhaps a megabyte)
  6115.  
  6116. This leaves three more switches which actually alter the game file which
  6117. Inform would compile:
  6118.  
  6119. `d'
  6120.      converts text like
  6121.  
  6122.           "...with a mango.  You applaud..."
  6123.  
  6124.      into the same with only a single space after the full stop, which
  6125.      will prevent an interpreter from displaying a spurious space at
  6126.      the beginning of a line when a line break happens to occur exactly
  6127.      after the full stop; this is to help typists who habitually
  6128.      double-space
  6129.  
  6130. `e'
  6131.      only in `economy' mode does Inform actually process abbreviations,
  6132.      because this is seldom needed and slows the compiler by 10% or so;
  6133.      the game file should not play any differently if compiled this
  6134.      way, but will probably be shorter, if your choice of abbreviations
  6135.      was sensible
  6136.  
  6137. `g'
  6138.      will make Inform automatically compile trace-printing code on every
  6139.      function call; in play this will produce reams of text (several
  6140.      pages between each chance to type commands) but is sometimes
  6141.      useful.  Note that in Inform 5.3 or later, this can be set on an
  6142.      individual command by writing `*' as its first local variable,
  6143.      without use of the `g' switch
  6144.  
  6145. `i'
  6146.      overrides any switches set by `switches' directives in the source
  6147.      code; so that the game can be compiled with different options
  6148.      without having to alter that source code.
  6149.  
  6150.  
  6151.  
  6152. E.2 Memory settings
  6153. ===================
  6154.  
  6155. Inform's memory management is about as flexible as it can be given that
  6156. it has to run in some quite hostile environments.  In particular, it is
  6157. unable to increase the size of any stretch of memory once allocated, so
  6158. if it runs out of anything it has to give up.  If it does run out, it
  6159. will produce an error message saying what it has run out of and how to
  6160. provide more.
  6161.  
  6162. There are two main choices: `$small' and `$large'.  (Which one is the
  6163. default depends on the computer you use.)  Even `$small' is large
  6164. enough to compile all the example games, including `Advent'.  `$large'
  6165. is large enough to compile almost anything (including the largest
  6166. version of `Curses' which ever existed, a draft very close to 256K
  6167. long).
  6168.  
  6169. A typical game, compiled with `$large', will cause Inform to allocate
  6170. about 336K of memory: and the same game about 100K less under `$small'.
  6171. (These values will be rather lower if the computer Inform runs on has
  6172. 16-bit integers.)  In addition, Inform physically occupies about 170K
  6173. (on my computer).  Thus, the total memory consumption of the compiler
  6174. at work will be between 4 to 500K.
  6175.  
  6176. Running
  6177.  
  6178.      inform $list
  6179.  
  6180. will list the various settings which can be changed, and their current
  6181. values.  Thus one can compare small and large with:
  6182.  
  6183.      inform $small $list
  6184.      inform $large $list
  6185.  
  6186. If Inform runs out of allocation for something, it will generally print
  6187. an error message like:
  6188.  
  6189.      "Game", line 1320: Fatal error: The memory setting MAX_OBJECTS (which
  6190.      is 200 at present) has been exceeded.  Try running Inform again with
  6191.      $MAX_OBJECTS=<some-larger-number> on the command line.
  6192.  
  6193. and indeed
  6194.  
  6195.      inform $MAX_OBJECTS=250 game
  6196.  
  6197. (say) will tell Inform to try again, reserving more memory for objects
  6198. this time.  Note that settings are made from left to right, so that for
  6199. instance
  6200.  
  6201.      inform $small $MAX_ACTIONS=200 ...
  6202.  
  6203. will work, but
  6204.  
  6205.      inform $MAX_ACTIONS=200 $small ...
  6206.  
  6207. will not because the `$small' changes `MAX_ACTIONS' again.
  6208.  
  6209. Changing some settings has hardly any effect on memory usage, whereas
  6210. others are expensive to increase.  To find out about, say, `MAX_VERBS',
  6211. run
  6212.  
  6213.      inform $?MAX_VERBS
  6214.  
  6215. (note the question mark, which may need to be escaped using e.g., `\?'
  6216. if your shell interprets `?' as a filename wildcard) which will print
  6217. some very brief comments.
  6218.  
  6219.  
  6220.  
  6221.  
  6222. F Answers to all the exercises
  6223. ******************************
  6224.  
  6225.  
  6226.  
  6227. F.1 Answer: the green cone
  6228. ==========================
  6229.  
  6230.      Nearby  cone "green cone"
  6231.       with   name "green" "cone" "emerald" "marzipan",
  6232.              describe [;
  6233.                  if (cone has moved)
  6234.                      "A misshapen cone of green marzipan sits here.";
  6235.                  "Nearby is an emerald green cone, one foot high.";
  6236.              ],
  6237.              description "The cone seems to be made of emerald-coloured \
  6238.                  marzipan.",
  6239.              before [;
  6240.               Eat:
  6241.                  if (random(100) <= 30) {
  6242.                      deadflag = 1;
  6243.                      "Unfortunately, you seem to be allergic to almonds.";
  6244.                  }
  6245.                  "You nibble at a corner of the cone.";
  6246.              ],
  6247.              after [;
  6248.               Take: "Taken.  (Your hands are smeared with marzipan.)";
  6249.               Drop:
  6250.                  cone.description = "The cone is a vague green mess.";
  6251.                  "The cone drops to the floor and sags a little.";
  6252.              ],
  6253.       has    edible;
  6254.  
  6255. The old `initial' message has gone.  Instead, we have provided a
  6256. `describe' routine.  Whenever the game has to describe the cone in the
  6257. description of a place, it will call this routine.  The `moved'
  6258. attribute is held only by an object which has at some time in the past
  6259. been taken.  So the cone is now perfect and untouched until taken and
  6260. dropped, whereupon it becomes misshapen.  Also, the act of dropping the
  6261. cone now changes the description which appears when a player examines
  6262. it.
  6263.  
  6264.  
  6265.  
  6266. F.2 Answer: actions
  6267. ===================
  6268.  
  6269. You may be surprised how many actions take place: often more than one
  6270. per turn.
  6271.  
  6272.  
  6273.  
  6274. F.3 Answer: property addresses
  6275. ==============================
  6276.  
  6277. `if (obj.&door_to == 0) { ... }'
  6278.  
  6279.  
  6280.  
  6281. F.4 Answer: world colours
  6282. =========================
  6283.  
  6284. Define four objects along the lines of:
  6285.  
  6286.      Object  white_obj "white wall" compass
  6287.       with   name "white" "sac" "wall",
  6288.              article "the",
  6289.              door_dir n_to
  6290.       has    direction scenery;
  6291.  
  6292. and add the following line to `Initialise':
  6293.  
  6294.      remove n_obj; remove e_obj; remove w_obj; remove s_obj;
  6295.  
  6296. (We could even `alias' a new property `white_to' to be `n_to', and then
  6297. enter map directions in the source code using Mayan property names.)
  6298. As a fine point of style, turquoise (*yax*) is the world colour for
  6299. `here', so add a grammar line to make this cause a `look':
  6300.  
  6301.      Verb "turquoise" "yax" * -> Look;
  6302.  
  6303.  
  6304.  
  6305. F.5 Answer: reflecting the map
  6306. ==============================
  6307.  
  6308.      [ SwapDirs o1 o2 x;
  6309.          x=o1.door_dir;
  6310.          o1.door_dir=o2.door_dir;
  6311.          o2.door_dir=x;
  6312.      ];
  6313.      [ ReflectWorld;
  6314.          SwapDirs(e_obj,w_obj);
  6315.          SwapDirs(ne_obj,nw_obj);
  6316.          SwapDirs(se_obj,sw_obj);
  6317.      ];
  6318.  
  6319.  
  6320.  
  6321. F.6 Answer: reflecting directions
  6322. =================================
  6323.  
  6324. This is a prime candidate for using variable strings `@nn', a topic
  6325. properly covered in the `Inform Technical Manual', but briefly: at the
  6326. head of the source, define
  6327.  
  6328.      Lowstring east_str "east";
  6329.      Lowstring west_str "west";
  6330.  
  6331. and then add two more routines to the game,
  6332.  
  6333.      [ NormalWorld;
  6334.          String 0 #east_str;
  6335.          String 1 #west_str;
  6336.      ];
  6337.      [ ReversedWorld;
  6338.          String 0 #west_str;
  6339.          String 1 #east_str;
  6340.      ];
  6341.  
  6342. where `NormalWorld' is called in `Initialise' or to go back to normal,
  6343. and `ReversedWorld' when the reflection happens.  Write `@00' in place
  6344. of `east' in any double-quoted printable string, and similarly `@01'
  6345. for `west'.  It will be printed as whichever is currently set.  (Inform
  6346. provides up to 32 such variable strings.)
  6347.  
  6348.  
  6349.  
  6350. F.7 Answer: medicine bottle
  6351. ===========================
  6352.  
  6353. Declare a fake action called, say, `OpenUp'.  Then:
  6354.  
  6355.      Object  medicine "guaranteed child-proof medicine bottle" cupboard
  6356.       with   name "medicine" "bottle",
  6357.              description "~Antidote only: no preventative effect.~",
  6358.              before [;
  6359.               Open, Unlock: "It's adult-proof too.";
  6360.               Openup:
  6361.                  give self open ~locked;
  6362.                  "The bottle cracks open!";
  6363.              ],
  6364.       has    container openable locked;
  6365.  
  6366. Any other code in the game can execute `<OpenUp medicine>' to crack
  6367. open the bottle.
  6368.  
  6369.  
  6370.  
  6371. F.8 Answer: two boxes
  6372. =====================
  6373.  
  6374.      Nearby  glass_box "glass box with a lid"
  6375.       with   name "glass" "box" "with" "lid"
  6376.       has    container transparent openable open;
  6377.      Nearby  steel_box "steel box with a lid"
  6378.       with   name "steel" "box" "with" "lid"
  6379.       has    container openable open;
  6380.  
  6381.  
  6382.  
  6383. F.9 Answer: toothed bag
  6384. =======================
  6385.  
  6386.      Object  bag "toothed bag" room
  6387.       with   name "toothed" "bag",
  6388.              description "A capacious bag with a toothed mouth.",
  6389.              before [;
  6390.               LetGo: "The bag defiantly bites itself shut on your hand \
  6391.                  until you desist.";
  6392.               Close: "The bag resists all attempts to close it.";
  6393.              ],
  6394.              after [;
  6395.               Receive:
  6396.                  print "The bag wriggles hideously as it swallows ";
  6397.                  DefArt(inp1); ".";
  6398.              ],
  6399.       has    container open;
  6400.  
  6401.  
  6402.  
  6403. F.10 Answer: television set
  6404. ===========================
  6405.  
  6406.      Object  television "portable television set" lounge
  6407.       with   name "tv" "television" "set" "portable",
  6408.              before [;
  6409.               SwitchOn: <<SwitchOn power_button>>;
  6410.               SwitchOff: <<SwitchOff power_button>>;
  6411.               Examine: <<Examine screen>>;
  6412.              ],
  6413.       has    transparent;
  6414.      Nearby  power_button "power button"
  6415.       with   name "power" "button" "switch",
  6416.              after [;
  6417.               SwitchOn, SwitchOff: <<Examine screen>>;
  6418.              ],
  6419.       has    switchable;
  6420.      Nearby  screen "television screen"
  6421.       with   name "screen",
  6422.              before [;
  6423.               Examine:
  6424.                  if (power_button hasnt on) "The screen is black.";
  6425.                  "The screen writhes with a strange Japanese cartoon.";
  6426.              ];
  6427.  
  6428.  
  6429.  
  6430. F.11 Answer: the red car
  6431. ========================
  6432.  
  6433. Change the car's `before' to
  6434.  
  6435.              before [;
  6436.               Go:
  6437.                  if (noun==d_obj or u_obj) {
  6438.                      print "(The car will never get over those stairs.)^";
  6439.                      rfalse;
  6440.                  }
  6441.                  if (car has on) "Brmm!  Brmm!";
  6442.                  print "(The ignition is off at the moment.)^";
  6443.              ],
  6444.  
  6445.  
  6446.  
  6447. F.12 Answer: *wayhel*
  6448. =====================
  6449.  
  6450. The common man's *wayhel* was a lowly mouse.  Since we think much more
  6451. highly of the player:
  6452.  
  6453.      Object  hog "Warthog" Caldera
  6454.       with   name "wart" "hog" "warthog", description "Muddy and grunting.",
  6455.              number 0,
  6456.              initial "A warthog snuffles and grunts about in the ash.",
  6457.              before [;
  6458.                  if (player==self && action~=##Go or ##Look or ##Examine)
  6459.                      "Warthogs can't do anything as tricky as that!";
  6460.              ],
  6461.       has    animate proper;
  6462.  
  6463. and we just `ChangePlayer(warthog);'.  Note that this `before' rule is
  6464. carefully written only to affect actions of the player-as-warthog.  If
  6465. the player-as-human should find and try to `take warthog', this
  6466. `before' routine won't interfere.
  6467.  
  6468.  
  6469.  
  6470. F.13 Answer: printing objects
  6471. =============================
  6472.  
  6473. Because `CDefArt(obj)' is a function call which, as it happens, returns
  6474. the value true, or 1 (not that this signifies anything), and `print'
  6475. thinks it is printing out a number.
  6476.  
  6477.  
  6478.  
  6479. F.14 Answer: the thief
  6480. ======================
  6481.  
  6482. This is a crude implementation, for brevity (the real Zork I thief has
  6483. an enormous stock of attached messages).
  6484.  
  6485.      Object  thief "thief" Danger_Zone
  6486.       with   name "thief",
  6487.              each_turn "^The thief growls menacingly.",
  6488.              daemon [ i p j n k;
  6489.                  if (random(3)~=1) rfalse;
  6490.                  p=parent(thief);
  6491.                  objectloop (i in compass) {
  6492.                      j=p.(i.door_dir);
  6493.                      if (j>player && j<=top_object && j hasnt door) n++;
  6494.                  }
  6495.                  if (n==0) rfalse;
  6496.                  k=random(n); n=0;
  6497.                  objectloop (i in compass) {
  6498.                      j=p.(i.door_dir);
  6499.                      if (j>player && j<=top_object && j hasnt door) n++;
  6500.                      if (n==k) {
  6501.                          move self to j;
  6502.                          if (p==location) "^The thief stalks away!";
  6503.                          if (j==location) "^The thief stalks in!";
  6504.                          rfalse;
  6505.                      }
  6506.                  }
  6507.              ];
  6508.  
  6509. This thief walks at random and cannot pass through doors, bridges and
  6510. the like (because these may be locked or have rules attached); it's only
  6511. a first approximation, and in a good game one should occasionally see
  6512. the thief do something surprising, such as open a secret door.
  6513.  
  6514.  
  6515.  
  6516. F.15 Answer: weights
  6517. ====================
  6518.  
  6519. First define a new property for object weight:
  6520.  
  6521.      Property weight 10;
  6522.  
  6523. (10 being an average sort of weight).  Containers weigh more when they
  6524. hold things, so we will need:
  6525.  
  6526.      [ WeightOf obj t i;
  6527.          t = obj.weight;
  6528.          objectloop (i in obj) t = t + WeightOf(i);
  6529.          return t;
  6530.      ];
  6531.  
  6532. Now for the daemon which monitors the player's fatigue:
  6533.  
  6534.      Object  weigher "weigher"
  6535.       with   number 500,
  6536.              time_left 5,
  6537.              daemon [ w s b bw;
  6538.                  w = WeightOf(player) - 100 - player.weight;
  6539.                  s = self.number;
  6540.                  s = s - w;
  6541.                  if (s <0) s = 0;
  6542.                  if (s > 500) s = 500;
  6543.                  self.number = s;
  6544.                  if (s == 0) {
  6545.                      bw = -1;
  6546.                      objectloop(b in player)
  6547.                          if (WeightOf(b) > bw) {
  6548.                              bw = WeightOf(b);
  6549.                              w = b;
  6550.                          }
  6551.                      print "^Exhausted with carrying so much, you decide \
  6552.                          to discard ";
  6553.                      DefArt(w);
  6554.                      print ": ";
  6555.                      <<Drop w>>;
  6556.                  }
  6557.                  w = s/100;
  6558.                  if (w == self.time_left) rfalse;
  6559.                  if (w == 3)
  6560.                      print "^You are feeling a little tired.^";
  6561.                  if (w == 2)
  6562.                      print "^You possessions are weighing you down.^";
  6563.                  if (w == 1)
  6564.                      print "^Carrying so much weight is wearing you out.^";
  6565.                  self.time_left = w;
  6566.              ];
  6567.  
  6568. Notice that items are actually dropped with `Drop' actions: one of them
  6569. might be, say, a wild boar, which would bolt away into the forest when
  6570. released.  The daemon tries to drop the heaviest item.  (Obviously a
  6571. little improvement would be needed if the game contained, say, an
  6572. un-droppable but very heavy ball and chain.)  Now the daemon is going to
  6573. run every turn forever, but needs to be started: so put
  6574. `StartDaemon(weigher);' into the game's `Initialise' routine.
  6575.  
  6576.  
  6577.  
  6578. F.16 Answer: passing midnight
  6579. =============================
  6580.  
  6581. Either set a daemon to watch for `the_time' suddenly dropping, or put
  6582. such a watch in the game's `TimePasses' routine.
  6583.  
  6584.  
  6585.  
  6586. F.17 Answer: suspended in mid-air
  6587. =================================
  6588.  
  6589. Because you don't know what order daemons will run in.  A `fatigue'
  6590. daemon which makes the player drop something might come after the
  6591. `mid-air' daemon has run for this turn.  Whereas `each_turn' happens
  6592. after daemons and timers have run their course, and can fairly assume
  6593. no further movements will take place this turn.
  6594.  
  6595.  
  6596.  
  6597. F.18 Answer: varying rates of time
  6598. ==================================
  6599.  
  6600. It would have to provide its own code to keep track of time, and it can
  6601. do this by providing a `TimePasses()' routine.  Providing `time' or
  6602. even `date' verbs to tell the player would also be a good idea.
  6603.  
  6604.  
  6605.  
  6606. F.19 Answer: footnotes
  6607. ======================
  6608.  
  6609.      Constant MAX_FOOTNOTES 10;
  6610.      global footnotes_seen data MAX_FOOTNOTES;
  6611.      global footnote_count;
  6612.      [ Note n i pn;
  6613.          for (i = 0: i < footnote_count: i++)
  6614.              if (n == footnotes_seen->i)
  6615.                  pn = i;
  6616.          if (footnote_count == MAX_FOOTNOTES)
  6617.              "** MAX_FOOTNOTES exceeded! **";
  6618.          if (pn == 0) {
  6619.              pn = footnote_count++;
  6620.              footnotes_seen->pn = n;
  6621.          }
  6622.          print " [", pn + 1, "]";
  6623.      ];
  6624.      [ FootnoteSub n;
  6625.          if (noun > footnote_count) {
  6626.              print "No footnote [",noun,"] has been mentioned.^";
  6627.              rtrue;
  6628.          }
  6629.          if (noun == 0) "Footnotes count upward from 1.";
  6630.          n = footnotes_seen->(noun-1);
  6631.          print "[", noun, "]  ";
  6632.          if (n==0) "This is a footnote.";
  6633.          if (n==1) "D.G.REG.F.D is inscribed around English coins.";
  6634.          if (n==2) "~Jackdaws love my big sphinx of quartz~, for example.";
  6635.      ];
  6636.      
  6637.      Verb "footnote" "note"
  6638.          * number                    -> Footnote;
  6639.  
  6640. And then call, for instance, `Note(1);' to refer in the game to the
  6641. `English coins' footnote.
  6642.  
  6643.  
  6644.  
  6645. F.20 Answer: unknown verbs
  6646. ==========================
  6647.  
  6648. Because the parser might go on to reject the line it's working on: for
  6649. instance, if the player typed `inventory splurge' then the message
  6650. `Shazam!' followed by a parser complaint will be somewhat unedifying.
  6651.  
  6652.  
  6653.  
  6654. F.21 Answer: control panel
  6655. ==========================
  6656.  
  6657. Here goes: we could implement the buttons with five separate objects,
  6658. essentially duplicates of each other.  (And by using a class definition,
  6659. this wouldn't look too bad.)  But if there were 500 slides this would be
  6660. less reasonable.
  6661.  
  6662.      [ ASlide w n;
  6663.          if (location ~= Machine_Room)       ! Slides only make sense in
  6664.              return -1;                      ! the Machine Room
  6665.          w = NextWord();
  6666.          if (w == 'slide') w = NextWord();
  6667.          n = 0;
  6668.          if (w == 'first' or 'one')   n=1;
  6669.          if (w == 'second' or 'two')  n=2;
  6670.          if (w == 'third' or 'three') n=3;
  6671.          if (w == 'fourth' or 'four') n=4;
  6672.          if (w == 'fifth' or 'five')  n=5;
  6673.          if (n == 0) return -1;              ! Failure!
  6674.          w = NextWord();
  6675.          if (w ~= 'slide') wn--;             ! Move word counter back to
  6676.                                              ! first misunderstood word
  6677.          parsed_number=n;
  6678.          return 1;                           ! Success!
  6679.      ];
  6680.      
  6681.      Global slide_settings data 10;          ! Ten bytes of data to hold
  6682.                                              ! five words for the settings
  6683.                                              ! (all initially zero)
  6684.      
  6685.      ! An interesting point here is that "noun" and "second" contain the
  6686.      ! appropriate numbers, and not objects: this all happens automatically
  6687.      
  6688.      [ SetSlideSub;
  6689.          slide_settings-->(noun-1) = second;
  6690.          print_ret "You set slide number ", noun,
  6691.              " to the value ", second, ".";
  6692.      ];
  6693.      
  6694.      [ XSlideSub;
  6695.          print_ret "Slide number ", noun, " currently stands at ",
  6696.              slide_settings-->(noun-1), ".";
  6697.      ];
  6698.      
  6699.      Extend "set" first
  6700.          * ASlide "to" number                -> SetSlide;
  6701.      Extend "push" first
  6702.          * ASlide "to" number                -> SetSlide;
  6703.      Extend "examine" first
  6704.          * ASlide                            -> XSlide;
  6705.  
  6706.  
  6707.  
  6708. F.22 Answer: quoted strings
  6709. ===========================
  6710.  
  6711. The blackboard code in `Toyshop' contains just such a routine:
  6712.  
  6713.      Global from_char; Global to_char;
  6714.      [ QuotedText i j f;
  6715.          i = parse->((++wn) * 4 - 3);
  6716.          if (buffer->i == '"') {
  6717.              for (j = i + 1: j <= (buffer->1) + 1: j++)
  6718.                 if (buffer->j == '"') f = j;
  6719.              if (f == 0) return -1;
  6720.              from_char = i + 1;
  6721.              to_char = f - 1;
  6722.              if (from_char>to_char) return -1;
  6723.              while (f > (parse->(wn * 4 - 3))) wn++;
  6724.              wn++;
  6725.              return 1;
  6726.          }
  6727.          return -1;
  6728.      ];
  6729.  
  6730. Note that in the case of success, the word marker `wn' is moved beyond
  6731. the last word accepted (since the Z-machine automatically tokenises a
  6732. double-quote as a single word).  The routine then tells the parser it
  6733. has parsed a number, which is a white lie.  What it actually does is to
  6734. record the byte positions where the quoted text starts and finishes in
  6735. the raw text `buffer' so that an action routine can easily extract the
  6736. text and use it later.  (Note that `""' with no text inside is not
  6737. matched by this routine but only because the last `if' statement throws
  6738. out that one case.)
  6739.  
  6740.  
  6741.  
  6742. F.23 Answer: named rooms
  6743. ========================
  6744.  
  6745. Define two properties:
  6746.  
  6747.      Property place_name;
  6748.      Property long to_places;
  6749.  
  6750. The scheme will work like this: a named room should have the
  6751. `place_name' property set to a single dictionary word; say, the
  6752. Bedquilt cave could be called `'bedquilt''.  Then in any room, a list
  6753. of those other rooms which can be moved to in this way should appear in
  6754. the `to_places' entry.  For instance,
  6755.  
  6756.      to_places Bedquilt Slab_Room Twopit_Room;
  6757.  
  6758. Now the code: see if a not-understood verb is a place name of a nearby
  6759. room, and if so store that room's object number in `goto_room',
  6760. converting the verb to a dummy.
  6761.  
  6762.      Global goto_room = 0;
  6763.      [ UnknownVerb word p i;
  6764.          p = location.&to_places;
  6765.          if (p == 0) rfalse;
  6766.          for (i = 0: (2 * i) < location.#to_places: i++)
  6767.              if (word == (p-->i).place_name) {
  6768.                  goto_room = p-->i;
  6769.                  return 'go#room';
  6770.              }
  6771.          rfalse;
  6772.      ];
  6773.      [ PrintVerb word;
  6774.          if (word=='go#room') {
  6775.              print "go to ";
  6776.              PrintShortName(goto_room);
  6777.              rtrue;
  6778.          }
  6779.          rfalse;
  6780.      ];
  6781.  
  6782. (The supplied `PrintVerb' is icing on the cake: so the parser can say
  6783. something like `I only understood you as far as wanting to go to
  6784. Bedquilt.' if need be.)  It remains only to put in code and grammar for
  6785. the dummy verb:
  6786.  
  6787.      [ GoRoomSub;
  6788.          if (goto_room hasnt visited)
  6789.              "But you have never been there.";
  6790.          PlayerTo(goto_room);
  6791.      ];
  6792.      Verb "go#room"
  6793.          *                                -> GoRoom;
  6794.  
  6795. Note that if you don't know the way, you can't go there!  A purist might
  6796. prefer instead to not recognise the name of an unvisited room, back at
  6797. the `UnknownVerb' stage, to avoid the player being able to deduce names
  6798. of nearby rooms from this `error message'.
  6799.  
  6800.  
  6801.  
  6802. F.24 Answer: purloin verb
  6803. =========================
  6804.  
  6805. A slight refinement of such a `purloin' verb is already defined in the
  6806. library (if the constant `DEBUG' is defined), so there's no need.
  6807. Here's how it could be done:
  6808.  
  6809.      [ Anything i;
  6810.          if (scope_stage==1) rfalse;
  6811.          if (scope_stage==2) {
  6812.              for (i=1:i<=top_object:i++) PlaceInScope(i);
  6813.              rtrue;
  6814.          }
  6815.          "No such in game.";
  6816.      ];
  6817.  
  6818. (This disallows multiple matches for efficiency reasons - the parser
  6819. has enough work to do with such a huge scope definition as it is.)  Now
  6820. the token `scope=Anything' will match anything at all, even things like
  6821. the abstract concept of `east'.
  6822.  
  6823.  
  6824.  
  6825. F.25 Answer: light switch
  6826. =========================
  6827.  
  6828. For good measure, we'll combine this with the previous rule about
  6829. `moved' objects being in scope in the dark.  The following can be
  6830. inserted into the `Shell' game:
  6831.  
  6832.      Object  coal "dull coal" Blank_Room
  6833.       with   name "dull" "coal";
  6834.      
  6835.      Object  Dark_Room "Dark Room"
  6836.       with   description "An empty room with a west exit.",
  6837.              each_turn [;
  6838.                  if (self has general) self.each_turn=0;
  6839.                  else "^You hear the breathing of a dwarf.";
  6840.              ],
  6841.              w_to Blank_Room;
  6842.      
  6843.      Nearby  light_switch "light switch"
  6844.       with   name "light" "switch",
  6845.              initial "On one wall is the light switch.",
  6846.              after [;
  6847.               SwitchOn: give Dark_Room light;
  6848.               SwitchOff: give Dark_Room ~light;
  6849.              ],
  6850.       has    switchable static;
  6851.      
  6852.      Nearby  diamond "shiny diamond"
  6853.       with   name "shiny" "diamond"
  6854.       has    scored;
  6855.      
  6856.      Nearby  dwarf "dwarf"
  6857.       with   name "voice" "dwarf",
  6858.              life [;
  6859.               Order:
  6860.                  if (action == ##SwitchOn && noun == light_switch) {
  6861.                      give Dark_Room light general;
  6862.                      give light_switch on;
  6863.                      "~Right you are, squire.~";
  6864.                  }
  6865.              ],
  6866.       has    animate;
  6867.      
  6868.      [ InScope person i;
  6869.          if (parent(person) == Dark_Room) {
  6870.              if (person == dwarf || Dark_Room has general)
  6871.                  PlaceInScope(light_switch);
  6872.          }
  6873.          if (person == player && location == thedark) {
  6874.              objectloop (i near player)
  6875.                  if (i has moved || i == dwarf)
  6876.                    PlaceInScope(i);
  6877.          }
  6878.          rfalse;
  6879.      ];
  6880.  
  6881. Note that the routine puts the light switch in scope for the dwarf - if
  6882. it didn't, the dwarf would not be able to understand `dwarf, turn light
  6883. on', and that was the whole point.
  6884.  
  6885.  
  6886.  
  6887. F.26 Answer: heliotropic troll
  6888. ==============================
  6889.  
  6890. Just test if `HasLightSource(gift)==1'.
  6891.  
  6892.  
  6893.  
  6894. F.27 Answer: double inventory
  6895. =============================
  6896.  
  6897.      [ DoubleInvSub i count1 count2;
  6898.          print "You are carrying ";
  6899.          objectloop (i in player) {
  6900.              if (i hasnt worn) { give i workflag; count1++; }
  6901.              else { give i ~workflag; count2++; }
  6902.          }
  6903.          if (count1==0) print "nothing.";
  6904.          else
  6905.              WriteListFrom(child(player), FULLINV_BIT + ENGLISH_BIT +
  6906.                  RECURSE_BIT + WORKFLAG_BIT);
  6907.          if (count2==0) ".";
  6908.          print ".  In addition, you are wearing ";
  6909.          objectloop (i in player) {
  6910.              if (i hasnt worn) give i ~workflag; else give i workflag;
  6911.          }
  6912.          WriteListFrom(child(player), ENGLISH_BIT + RECURSE_BIT +
  6913.              WORKFLAG_BIT);
  6914.          ".";
  6915.      ];
  6916.  
  6917.  
  6918.  
  6919. F.28 Answer: cherubim
  6920. =====================
  6921.  
  6922.      Global  c_warned = 0;
  6923.      Class   cherub_class
  6924.       with   parse_name [ i j flag;
  6925.                  for (flag = 1: flag == 1: flag = 0) {
  6926.                      j=NextWord();
  6927.                      if (j=='cherub' or j==self.name) flag=1;
  6928.                      if (j=='cherubs' && c_warned==0) {
  6929.                          c_warned=1;
  6930.                          parser_action=##PluralFound;
  6931.                          flag=1;
  6932.                          print "(I'll let this go once, but the plural of \
  6933.                              cherub is cherubim.)^";
  6934.                      }
  6935.                      if (j=='cherubim') {
  6936.                          parser_action=##PluralFound;
  6937.                          flag=1;
  6938.                      }
  6939.                      i++;
  6940.                  }
  6941.                  return i-1;
  6942.              ];
  6943.  
  6944. Then again, Shakespeare even writes `cherubins' in `Twelfth Night', so
  6945. who are we to censure?
  6946.  
  6947.  
  6948.  
  6949. F.29 Answer: status line
  6950. ========================
  6951.  
  6952. First put the directive `Replace DrawStatusLine;' before including the
  6953. library.  Then add the following routine anywhere after
  6954. `treasures_found', an `Advent' variable, is defined:
  6955.  
  6956.      [ DrawStatusLine;
  6957.          @split_window 1; @set_window 1; @set_cursor 1 1; style reverse;
  6958.          spaces (0->33)-1;
  6959.          @set_cursor 1 2;  PrintShortName(location);
  6960.          if (treasures_found > 0) {
  6961.              @set_cursor 1 50; print "Treasure: ", treasures_found;
  6962.          }
  6963.          @set_cursor 1 1; style roman; @set_window 0;
  6964.      ];
  6965.  
  6966.  
  6967.  
  6968. F.30 Answer: invisiclues
  6969. ========================
  6970.  
  6971. Note the magic line of assembly code here, which only works for Advanced
  6972. games:
  6973.  
  6974.      [ GiveHint hint keypress;
  6975.          print_paddr hint; new_line; new_line;
  6976.          @read_char 1 0 0 keypress;
  6977.          if (keypress == 'H' or 'h') rfalse;
  6978.          rtrue;
  6979.      ];
  6980.  
  6981. And a typical menu item using it:
  6982.  
  6983.      if (menu_item==1) {
  6984.          print "(Press ENTER to return to menu, or H for another hint.)^^";
  6985.          if (GiveHint("(1/3)  What kind of bird is it, exactly?") == 1)
  6986.              return 2;
  6987.          if (GiveHint("(2/3)  Magpies are attracted by shiny items.") == 1)
  6988.              return 2;
  6989.          "(3/3)  Wave at the magpie with the kitchen foil.";
  6990.      }
  6991.  
  6992.  
  6993.  
  6994. F.31 Answer: primes
  6995. ===================
  6996.  
  6997. `Primes(100)', where:
  6998.  
  6999.      [ Primes i j k l;
  7000.          for (j = 2: j <= i: j++) {
  7001.              print j, " : ";
  7002.              l=j;
  7003.              while (l > 1)
  7004.                  for (k=2: k<=l: k++)
  7005.                      if (l % k == 0) {
  7006.                          l=l/k;
  7007.                          print k, " ";
  7008.                          break;
  7009.                      }
  7010.              new_line;
  7011.          }
  7012.      ];
  7013.  
  7014. (which was the first algorithm ever compiled by Inform).
  7015.  
  7016.  
  7017.  
  7018.  
  7019. G Index of concepts
  7020. *******************
  7021.  
  7022. * Menu:
  7023.  
  7024. * `Acheton':                            Credits.
  7025. * `Advent':                             Memory settings.
  7026. * `Advent':                             The player.
  7027. * `Advent':                             Classes of objects.
  7028. * `Advent':                             Misc grammar.
  7029. * `Advent':                             About daemons.
  7030. * `Advent':                             Status line.
  7031. * `Advent':                             Compiler options.
  7032. * `Balances':                           Plural names.
  7033. * `Balances':                           Extending.
  7034. * `Colossal Cave':                      Misc grammar.
  7035. * `Curses':                             Memory settings.
  7036. * `Curses':                             Object definitions.
  7037. * `Enchanter':                          Doors.
  7038. * `Hello Cruel World':                  Shell.
  7039. * `Shell':                              Shell.
  7040. * `Spellbreaker':                       Library actions.
  7041. * `Spellbreaker':                       The player.
  7042. * `The Legend Lives':                   Numbers.
  7043. * `Toyshop':                            Changing lists.
  7044. * `Toyshop':                            Answer (quoted strings).
  7045. * `Toyshop':                            About daemons.
  7046. * `Trinity':                            Room code.
  7047. * `Zork I':                             Each turn.
  7048. * `Zork I':                             About daemons.
  7049. * `Zork':                               Switches.
  7050. * `Zork':                               Z-machine.
  7051. * abbreviations:                        Compiler options.
  7052. * abbreviations:                        Limitations.
  7053. * abstract verb:                        Debugging verbs.
  7054. * action groups:                        Library actions.
  7055. * action numbers:                       Causing actions.
  7056. * actions:                              Debugging verbs.
  7057. * actions:                              Causing actions.
  7058. * actions:                              Basic ingredients.
  7059. * actions:                              Invoking actions.
  7060. * actions verb:                         Debugging verbs.
  7061. * actions verb:                         Basic ingredients.
  7062. * addresses:                            Z-machine.
  7063. * Advanced games:                       Dirty tricks.
  7064. * Advanced games:                       Z-machine.
  7065. * Advanced games:                       Styles.
  7066. * Advanced games:                       Object definitions.
  7067. * Advanced games:                       Properties.
  7068. * Advanced games:                       Warnings.
  7069. * Advanced games:                       Limitations.
  7070. * Advanced games:                       Compiler options.
  7071. * almond poisoning:                     Adding code.
  7072. * Anderson, Timothy:                    Vehicles.
  7073. * appallingly convenient verb:          Tokens.
  7074. * archaeological dig:                   Each turn.
  7075. * Area 400:                             Naming of names.
  7076. * Aristotle:                            Objects.
  7077. * arithmetic operators:                 Operators.
  7078. * arrays:                               Variables and arrays.
  7079. * asking questions:                     Changing scope.
  7080. * assembler errors:                     Internal and assembler errors.
  7081. * assembly language:                    Dirty tricks.
  7082. * assignments:                          Assignments.
  7083. * attributes:                           Simple objects.
  7084. * attributes:                           Attributes.
  7085. * attributes in library:                Library attributes.
  7086. * Auden, W. H.:                         Doors.
  7087. * audibility:                           Each turn.
  7088. * background daemon:                    About daemons.
  7089. * backslash:                            File format.
  7090. * backslash:                            Quoted strings.
  7091. * bag of six coins:                     Plural names.
  7092. * Baggett, David M.:                    Numbers.
  7093. * Baggett, David M.:                    The player.
  7094. * banana:                               Tokens.
  7095. * batteries:                            Switches.
  7096. * Bedquilt Room:                        New actions.
  7097. * Beerbohm, Max:                        Scope.
  7098. * binary:                               Constants.
  7099. * blackboard:                           Answer (quoted strings).
  7100. * Blank, Marc:                          Vehicles.
  7101. * Blank, Marc:                          Doors.
  7102. * blocks of code:                       Blocks of code.
  7103. * boldface:                             Styles.
  7104. * bolted cupboard:                      Other containers.
  7105. * Booth, Connie:                        Special effects.
  7106. * brace mismatch:                       Errors.
  7107. * braces:                               Blocks of code.
  7108. * brain transference machine:           The player.
  7109. * brass lantern:                        Switches.
  7110. * built-in functions:                   Built-in functions.
  7111. * byte address:                         Z-machine.
  7112. * Cambridge University:                 Credits.
  7113. * ceiling:                              Library objects.
  7114. * chair:                                The player.
  7115. * changing scope:                       Global scope.
  7116. * changing the player:                  The player.
  7117. * character graphic:                    Fixed font.
  7118. * cherubim:                             Answer (cherubim).
  7119. * cherubim:                             Plural names.
  7120. * Chesterton, G. K.:                    Printing of names.
  7121. * Christopher, John:                    Places.
  7122. * class errors:                         Errors.
  7123. * classes:                              Classes of objects.
  7124. * clearing the screen:                  Dirty tricks.
  7125. * Cleese, John:                         Special effects.
  7126. * closing credits:                      Amusing.
  7127. * clues:                                Menus.
  7128. * command line syntax:                  Compiler options.
  7129. * comments:                             File format.
  7130. * companion volumes:                    History.
  7131. * compiler switches:                    Compiler options.
  7132. * conditional compilation:              Directives.
  7133. * conditional compilation:              Errors.
  7134. * conditions:                           Conditions.
  7135. * constants:                            Constants.
  7136. * control constructs:                   Control constructs.
  7137. * copyright:                            Copyright.
  7138. * crashing the interpreter:             Crashes.
  7139. * creature token:                       Tokens.
  7140. * crowns:                               Plural names.
  7141. * Crowther, Willie:                     Credits.
  7142. * crystal chandelier:                   Map.
  7143. * cursor keys:                          Dirty tricks.
  7144. * daemon running order:                 Answer (suspended in mid-air).
  7145. * daemons:                              Debugging verbs.
  7146. * daemons:                              About daemons.
  7147. * darkness:                             Scope rules.
  7148. * de la Bruyère, Jean:                 The player.
  7149. * de Montaigne, Michel:                 Creatures.
  7150. * debugging code:                       Trace.
  7151. * debugging information file:           Compiler options.
  7152. * debugging verbs:                      Debugging verbs.
  7153. * default value of properties:          Properties.
  7154. * definite article:                     Printing of names.
  7155. * definition of darkness:               Light.
  7156. * dentist's chair:                      Vehicles.
  7157. * depressed philosophers:               The player.
  7158. * dictionary errors:                    Errors.
  7159. * dictionary resolution:                Limitations.
  7160. * dictionary words:                     Library properties.
  7161. * direction objects:                    Library objects.
  7162. * direction objects:                    Answer (world colours).
  7163. * direction objects:                    Library properties.
  7164. * direction objects):                   Room code.
  7165. * direction properties:                 Library properties.
  7166. * directions:                           Map.
  7167. * directions:                           Scope rules.
  7168. * directive:                            Attributes.
  7169. * directives:                           Directives.
  7170. * dirty tricks:                         Dirty tricks.
  7171. * displays beautiful:                   Boxes.
  7172. * division by zero:                     Assignments.
  7173. * Donne, John:                          Places.
  7174. * double inventory:                     Answer (double inventory).
  7175. * double inventory:                     Lists.
  7176. * double spacing:                       Compiler options.
  7177. * double-quote:                         Answer (quoted strings).
  7178. * dramatic effects:                     Global scope.
  7179. * drawings:                             Fixed font.
  7180. * drunk player object:                  The player.
  7181. * dummy verb:                           Answer (named rooms).
  7182. * earshot:                              Each turn.
  7183. * economy mode:                         Compiler options.
  7184. * Eliot, T. S.:                         Naming of names.
  7185. * embedded routines:                    Object definitions.
  7186. * embedded routines:                    Routines.
  7187. * entry points:                         Library entry points.
  7188. * epigrams:                             Boxes.
  7189. * error messages:                       Error messages.
  7190. * exotic forms of death:                The player.
  7191. * expression errors:                    Errors.
  7192. * expressions:                          Operators.
  7193. * fake actions:                         Causing actions.
  7194. * fake actions:                         Creatures.
  7195. * fake actions:                         Basic containers.
  7196. * fake actions:                         Plural names.
  7197. * fatal errors:                         Fatal errors.
  7198. * fatigue daemon:                       Answer (weights).
  7199. * file format:                          File format.
  7200. * flags:                                Attributes.
  7201. * flexible verbs:                       Misc grammar.
  7202. * floating object:                      Library attributes.
  7203. * floor:                                Library objects.
  7204. * fluorescent jellyfish:                Light.
  7205. * focus of game:                        The player.
  7206. * footnotes:                            Numbers.
  7207. * footnotes:                            Answer (footnotes).
  7208. * foreign character sets:               Quoted strings.
  7209. * Frankenstein:                         The player.
  7210. * free verb:                            Tokens.
  7211. * function arguments:                   Routines.
  7212. * function keys:                        Dirty tricks.
  7213. * fuses:                                Timers.
  7214. * Gilbert, W. S.:                       Inventories.
  7215. * glass box:                            Basic containers.
  7216. * global variables:                     Errors.
  7217. * Goldsmith, Oliver:                    Limitations.
  7218. * goto verb:                            Debugging verbs.
  7219. * Grammar:                              Basic ingredients.
  7220. * Grammar:                              Shell.
  7221. * grammar lines:                        New verbs.
  7222. * grammar tokens:                       Tokens.
  7223. * grammatical errors:                   Errors.
  7224. * green cone:                           Simple objects.
  7225. * grues:                                Changing scope.
  7226. * hacker and urchin:                    Creatures.
  7227. * hanging elses:                        Blocks of code.
  7228. * hangover:                             Object definitions.
  7229. * has light:                            Light.
  7230. * hash character:                       Directives.
  7231. * held token:                           Tokens.
  7232. * hexadecimal:                          Properties.
  7233. * Ideas, Ivan O.:                       Scoring.
  7234. * in scope:                             Scope rules.
  7235. * indefinite article:                   Printing of names.
  7236. * indistinguishable:                    Plural names.
  7237. * Infact:                               Infix.
  7238. * Infix:                                Compiler options.
  7239. * Infix:                                Infix.
  7240. * Infocom, Inc.:                        Credits.
  7241. * Inform 5.2:                           Credits.
  7242. * InfoTaskForce:                        Dirty tricks.
  7243. * inheritance:                          Object definitions.
  7244. * inheritance:                          Classes of objects.
  7245. * initial possessions:                  The player.
  7246. * internal errors:                      Internal and assembler errors.
  7247. * interpreter:                          Z-machine.
  7248. * interpreters:                         Dirty tricks.
  7249. * inventories:                          Changing lists.
  7250. * Invisiclues:                          Answer (invisiclues).
  7251. * Invisiclues:                          Menus.
  7252. * junior astronaut:                     Library entry points.
  7253. * keyboard:                             Dirty tricks.
  7254. * Kierkegaard, Søren:                  The player.
  7255. * labels:                               Labels.
  7256. * large memory:                         Memory settings.
  7257. * Lebling, P. David:                    Containers.
  7258. * Lebling, P. David:                    Vehicles.
  7259. * Lebling, P. David:                    Doors.
  7260. * Lewis, C. S.:                         Library.
  7261. * Lewis, C. S.:                         Daemons.
  7262. * lexicon:                              Basic ingredients.
  7263. * library:                              Ingredients.
  7264. * library routines:                     Library routines.
  7265. * light and dark:                       Light.
  7266. * light switch:                         Answer (light switch).
  7267. * light switch:                         Global scope.
  7268. * limitations:                          Limitations.
  7269. * line of sight:                        Each turn.
  7270. * listing objects:                      Lists.
  7271. * little red car:                       Answer (the red car).
  7272. * little red car:                       Vehicles.
  7273. * local variables:                      Variables and arrays.
  7274. * Long Count:                           Changing scope.
  7275. * loop over every object:               Control constructs.
  7276. * low mist:                             Causing actions.
  7277. * low numbers in French:                Numbers.
  7278. * MacNeice, Louis:                      Introduction.
  7279. * making actions:                       New actions.
  7280. * making attributes:                    Attributes.
  7281. * making grammar:                       New actions.
  7282. * making grammar:                       New verbs.
  7283. * making properties:                    Properties.
  7284. * map:                                  Doors.
  7285. * map:                                  Map.
  7286. * master catburglar:                    Library entry points.
  7287. * matchbook:                            Changing lists.
  7288. * Mayan directions:                     Answer (world colours).
  7289. * Mayan directions:                     Room code.
  7290. * me:                                   The player.
  7291. * medicine bottle:                      New actions.
  7292. * memory consumption:                   Memory settings.
  7293. * memory management:                    Memory settings.
  7294. * memory map:                           Z-machine.
  7295. * memory settings:                      Memory settings.
  7296. * memory settings:                      Fatal errors.
  7297. * memory size:                          Limitations.
  7298. * menu of text options:                 Menus.
  7299. * mid-air location:                     Each turn.
  7300. * Molière:                             The parser.
  7301. * moving the player:                    The player.
  7302. * multiexcept token:                    Tokens.
  7303. * multiheld token:                      Tokens.
  7304. * myself:                               The player.
  7305. * nagual:                               Answer (wayhel).
  7306. * nagual:                               The player.
  7307. * named rooms:                          Misc grammar.
  7308. * named rooms:                          Answer (named rooms).
  7309. * narrow inventory:                     Lists.
  7310. * Nelson, Graham:                       Copyright.
  7311. * NetHack:                              Dirty tricks.
  7312. * normal rules:                         Causing actions.
  7313. * normal rules:                         Library attributes.
  7314. * notify verb:                          Score.
  7315. * noun token:                           Tokens.
  7316. * number token:                         Tokens.
  7317. * number-parsing:                       Numbers.
  7318. * numbers:                              Z-machine.
  7319. * object definitions:                   Object definitions.
  7320. * object errors:                        Errors.
  7321. * Object syntax:                        Object definitions.
  7322. * objects:                              Object tree.
  7323. * objects in library:                   Library objects.
  7324. * offers light:                         Light.
  7325. * ogre with limited patience:           Each turn.
  7326. * out verb:                             Vehicles.
  7327. * output streams:                       Dirty tricks.
  7328. * oyster:                               New actions.
  7329. * packed address:                       Z-machine.
  7330. * Parker, Dorothy:                      Boxes.
  7331. * Parser:                               Shell.
  7332. * parser:                               The parser.
  7333. * parser questions:                     Misc grammar.
  7334. * parser speed:                         Errors.
  7335. * parser tracing and levels:            Trace.
  7336. * parsing quoted strings:               Misc grammar.
  7337. * parsing quoted strings:               Answer (quoted strings).
  7338. * passing messages:                     New actions.
  7339. * Pepper Room:                          Causing actions.
  7340. * perfectly sensible:                   Properties.
  7341. * Peter and Jane:                       Constants.
  7342. * pinfocom:                             Dirty tricks.
  7343. * plagiarism:                           Scoring.
  7344. * plaster of paris:                     Vehicles.
  7345. * player's origin:                      The player.
  7346. * plural objects:                       Plural names.
  7347. * Pope, Alexander:                      Daemons.
  7348. * precedence:                           Classes of objects.
  7349. * prime factorisations:                 Answer (primes).
  7350. * prime factorisations:                 Control constructs.
  7351. * printing commands:                    Printing commands.
  7352. * proper noun:                          Printing of names.
  7353. * properties:                           Simple objects.
  7354. * properties:                           Properties.
  7355. * properties in library:                Library properties.
  7356. * proportional font:                    Fixed font.
  7357. * puff of garlic:                       Printing commands.
  7358. * purloin verb:                         Debugging verbs.
  7359. * purloin verb:                         Changing scope.
  7360. * purloin verb:                         Answer (purloin verb).
  7361. * questions:                            Changing scope.
  7362. * questions (yes or no):                Yes or no.
  7363. * quoted text:                          Answer (quoted strings).
  7364. * quotes off verb:                      Boxes.
  7365. * radio:                                Each turn.
  7366. * rainbows:                             Map.
  7367. * real time:                            Dirty tricks.
  7368. * Rees, Gareth:                         History.
  7369. * reflecting the map:                   Answer (reflecting the map).
  7370. * reflecting the map):                  Room code.
  7371. * release number:                       Directives.
  7372. * replacing grammar:                    Extending.
  7373. * resurrection:                         The player.
  7374. * returning from routines:              Returning from routines.
  7375. * reusing attributes:                   Attributes.
  7376. * reverse video:                        Styles.
  7377. * roman text:                           Styles.
  7378. * routine errors:                       Errors.
  7379. * routine tracing:                      Trace.
  7380. * routines:                             Routines.
  7381. * routines verb:                        Debugging verbs.
  7382. * rucksack:                             Tokens.
  7383. * run-time crashes:                     Crashes.
  7384. * run-time format:                      Limitations.
  7385. * running out of memory:                Fatal errors.
  7386. * rusty door:                           Doors.
  7387. * scope:                                Scope rules.
  7388. * score notification:                   Score.
  7389. * score verb:                           Misc grammar.
  7390. * scoring systems:                      Score.
  7391. * screen tricks:                        Dirty tricks.
  7392. * Seal, David:                          Credits.
  7393. * searchlight:                          Switches.
  7394. * see-through:                          Scope rules.
  7395. * serial number:                        Directives.
  7396. * Shakespeare, William:                 Scope.
  7397. * Shakespeare, William:                 Answer (cherubim).
  7398. * Shaw, George Bernard:                 Scope.
  7399. * shazam verb:                          Misc grammar.
  7400. * Shirley, James:                       Actions.
  7401. * silver bars:                          Classes of objects.
  7402. * Sloping Corridor:                     Map.
  7403. * small array:                          Properties.
  7404. * small memory:                         Memory settings.
  7405. * snavig spell:                         The player.
  7406. * Snow, C. P.:                          Light.
  7407. * sound effect:                         Dirty tricks.
  7408. * source-level debugger:                Infix.
  7409. * Space Invaders:                       Dirty tricks.
  7410. * spaceship control panel:              Misc grammar.
  7411. * spaceship control panel:              Answer (control panel).
  7412. * special effects:                      Special effects.
  7413. * special objects:                      Library objects.
  7414. * special token:                        Tokens.
  7415. * Spellbreaker cubes:                   Plural names.
  7416. * Square Room:                          Map.
  7417. * stack pointer:                        Variables and arrays.
  7418. * Standard games:                       Z-machine.
  7419. * Standard games:                       Compiler options.
  7420. * Standard games:                       Dirty tricks.
  7421. * Standard games:                       Warnings.
  7422. * Standard games:                       Attributes.
  7423. * Standard games:                       Object definitions.
  7424. * Standard games:                       Limitations.
  7425. * Standard games:                       Properties.
  7426. * statistics:                           Compiler options.
  7427. * status line:                          Status line.
  7428. * status line:                          Crashes.
  7429. * steel box:                            Basic containers.
  7430. * steel grate:                          Doors.
  7431. * story files:                          Inform.
  7432. * stream:                               Each turn.
  7433. * style of list:                        Lists.
  7434. * sullen snake:                         Creatures.
  7435. * switches (on command line):           Compiler options.
  7436. * sword:                                Each turn.
  7437. * symbol names:                         Errors.
  7438. * synonyms:                             New verbs.
  7439. * take verb:                            New verbs.
  7440. * Tartt, Donna:                         Actions.
  7441. * tasty food:                           Object definitions.
  7442. * team of four adventurers:             The player.
  7443. * teleportation:                        The player.
  7444. * television set:                       Other containers.
  7445. * television set:                       Answer (television set).
  7446. * Tera:                                 Credits.
  7447. * Texinfo:                              History.
  7448. * text style:                           Styles.
  7449. * Thackray, Jonathan:                   Credits.
  7450. * The Prisoner:                         Vehicles.
  7451. * thief in `Zork I':                    About daemons.
  7452. * thief in `Zork I':                    Answer (the thief).
  7453. * thief in `Zork I':                    Each turn.
  7454. * tidying-up operations:                About daemons.
  7455. * time of day:                          Each turn.
  7456. * time sequence:                        Each turn.
  7457. * timed input:                          Dirty tricks.
  7458. * timers:                               Timers.
  7459. * timers:                               Debugging verbs.
  7460. * timers verb:                          Debugging verbs.
  7461. * toffee apple:                         Causing actions.
  7462. * token for `any object':               Answer (purloin verb).
  7463. * tokenisation:                         Answer (quoted strings).
  7464. * tokens:                               Tokens.
  7465. * toothed bag:                          Answer (toothed bag).
  7466. * toothed bag:                          Basic containers.
  7467. * trace verb:                           Debugging verbs.
  7468. * tracing a routine:                    Trace.
  7469. * tracing routines:                     Debugging verbs.
  7470. * tracing the parser:                   Trace.
  7471. * transcript:                           Dirty tricks.
  7472. * treasure class:                       Classes of objects.
  7473. * tree of objects:                      Object tree.
  7474. * tree verb:                            Debugging verbs.
  7475. * troll:                                Light.
  7476. * two-way door:                         Doors.
  7477. * txd (disassembler):                   Crashes.
  7478. * types (lack of):                      Properties.
  7479. * underlining:                          Styles.
  7480. * undo verb:                            Limitations.
  7481. * undo verb:                            Dirty tricks.
  7482. * urchin and hacker:                    Creatures.
  7483. * valuable cake:                        Classes of objects.
  7484. * variable strings:                     Answer (reflecting directions).
  7485. * variables:                            Variables and arrays.
  7486. * vehicles:                             Vehicles.
  7487. * VerbLib:                              Shell.
  7488. * version 6:                            Limitations.
  7489. * very last resort:                     Replace.
  7490. * vocabulary size:                      Limitations.
  7491. * VT100:                                Styles.
  7492. * walls:                                Library objects.
  7493. * wandering monsters:                   About daemons.
  7494. * warnings:                             Warnings.
  7495. * warthog:                              Answer (wayhel).
  7496. * weights:                              Answer (weights).
  7497. * weights:                              About daemons.
  7498. * weird thing:                          Naming of names.
  7499. * what is a grue:                       Changing scope.
  7500. * wide inventory:                       Lists.
  7501. * Wittgenstein, Ludwig:                 The parser.
  7502. * Wittgenstein, Ludwig:                 Creatures.
  7503. * woodpecker:                           Debugging.
  7504. * Woods, Don:                           Credits.
  7505. * world colours:                        Answer (world colours).
  7506. * world colours:                        Room code.
  7507. * xyzzy verb:                           New verbs.
  7508. * Z-machine:                            Z-machine.
  7509. * zero:                                 Numbers.
  7510. * Zip:                                  Dirty tricks.
  7511. * Zip:                                  Crashes.
  7512. * Zip:                                  Infix.
  7513. * zterp:                                Dirty tricks.
  7514.  
  7515.  
  7516.  
  7517.  
  7518. H Index of functions, properties, attributes etc
  7519. ************************************************
  7520.  
  7521. * Menu:
  7522.  
  7523. * *:                                    Trace.
  7524. * *:                                    Routines.
  7525. * ++:                                   Errors.
  7526. * -:                                    Errors.
  7527. * ->:                                   Variables and arrays.
  7528. * ->:                                   Variables and arrays.
  7529. * ->:                                   New verbs.
  7530. * @@:                                   Quoted strings.
  7531. * @nn:                                  Answer (reflecting directions).
  7532. * absent:                               Library attributes.
  7533. * Achieved:                             Library routines.
  7534. * Achieved(task):                       Score.
  7535. * actor:                                Global scope.
  7536. * additive:                             Properties.
  7537. * additive:                             Classes of objects.
  7538. * after:                                Simple objects.
  7539. * after:                                Library properties.
  7540. * after:                                Library actions.
  7541. * after:                                Room code.
  7542. * AfterLife:                            Library entry points.
  7543. * AfterLife:                            The player.
  7544. * alias:                                Errors.
  7545. * alias:                                Properties.
  7546. * alias:                                Attributes.
  7547. * AllowPushDir:                         Library routines.
  7548. * AllowPushDir:                         Vehicles.
  7549. * ALWAYS_BIT:                           Lists.
  7550. * Amusing:                              Library entry points.
  7551. * AMUSING_PROVIDED:                     Amusing.
  7552. * AMUSING_PROVIDED:                     Library constants.
  7553. * animate:                              Library attributes.
  7554. * ANIMA_PE:                             Parser errors.
  7555. * Answer:                               Creatures.
  7556. * aread:                                Dirty tricks.
  7557. * article:                              Printing of names.
  7558. * article:                              Library properties.
  7559. * Ask:                                  Creatures.
  7560. * ASKSCOPE_PE:                          Parser errors.
  7561. * Attack:                               Creatures.
  7562. * Attribute:                            Attributes.
  7563. * autosearch:                           Library attributes.
  7564. * beep:                                 Dirty tricks.
  7565. * before:                               Library properties.
  7566. * before:                               Adding code.
  7567. * Blorple:                              New actions.
  7568. * box:                                  Boxes.
  7569. * break:                                Control constructs.
  7570. * buffer_mode:                          Dirty tricks.
  7571. * CANTSEE_PE:                           Parser errors.
  7572. * cant_go:                              Map.
  7573. * cant_go:                              Library properties.
  7574. * capacity:                             Basic containers.
  7575. * capacity:                             Library properties.
  7576. * capacity:                             The player.
  7577. * CDefArt:                              Library routines.
  7578. * CDefArt(obj):                         Printing of names.
  7579. * ChangePlayer:                         Library routines.
  7580. * ChangePlayer:                         The player.
  7581. * child:                                Crashes.
  7582. * child:                                Object tree.
  7583. * children:                             Crashes.
  7584. * class:                                Object definitions.
  7585. * Class:                                Object definitions.
  7586. * class:                                Classes of objects.
  7587. * clothing:                             Library attributes.
  7588. * compass:                              Library objects.
  7589. * concealed:                            Scope rules.
  7590. * concealed:                            Library attributes.
  7591. * container:                            Basic containers.
  7592. * container:                            Library attributes.
  7593. * daemon:                               About daemons.
  7594. * daemon:                               Library properties.
  7595. * DarkToDark:                           Library entry points.
  7596. * DarkToDark:                           Light.
  7597. * data:                                 Variables and arrays.
  7598. * deadflag:                             The player.
  7599. * deadflag:                             Adding code.
  7600. * DeathMessage:                         The player.
  7601. * DeathMessage:                         Library entry points.
  7602. * DEBUG:                                Library constants.
  7603. * DEBUG:                                Basic ingredients.
  7604. * DEBUG:                                Debugging verbs.
  7605. * DefArt:                               Library routines.
  7606. * DefArt(obj):                          Printing of names.
  7607. * DEFART_BIT:                           Lists.
  7608. * describe:                             Library properties.
  7609. * describe:                             Object definitions.
  7610. * description:                          Library properties.
  7611. * direction:                            Library attributes.
  7612. * DoMenu:                               Library routines.
  7613. * DoMenu:                               Menus.
  7614. * door:                                 Doors.
  7615. * door:                                 Library attributes.
  7616. * door_dir:                             Doors.
  7617. * door_dir:                             Doors.
  7618. * door_dir:                             Library properties.
  7619. * door_to:                              Library properties.
  7620. * door_to:                              Doors.
  7621. * d_obj:                                Library objects.
  7622. * each_turn:                            Library properties.
  7623. * each_turn:                            Each turn.
  7624. * edible:                               Library attributes.
  7625. * elder:                                Object tree.
  7626. * eldest:                               Object tree.
  7627. * EnglishNumber:                        Library routines.
  7628. * ENGLISH_BIT:                          Lists.
  7629. * Enter:                                Doors.
  7630. * enterable:                            Library attributes.
  7631. * enterable:                            Vehicles.
  7632. * erase_window:                         Dirty tricks.
  7633. * et_flag:                              Each turn.
  7634. * EXCEPT_PE:                            Parser errors.
  7635. * Extend:                               Extending.
  7636. * e_obj:                                Library objects.
  7637. * Fake Action:                          New actions.
  7638. * female:                               Library attributes.
  7639. * first:                                Extending.
  7640. * font:                                 Fixed font.
  7641. * for:                                  Control constructs.
  7642. * found_in:                             Library properties.
  7643. * found_in:                             Properties.
  7644. * found_in:                             Causing actions.
  7645. * FULLINV_BIT:                          Lists.
  7646. * GamePostRoutine:                      Library entry points.
  7647. * GamePostRoutine:                      New actions.
  7648. * GamePreRoutine:                       Library entry points.
  7649. * GamePreRoutine:                       New actions.
  7650. * general:                              Library attributes.
  7651. * Give:                                 Creatures.
  7652. * give:                                 Attributes.
  7653. * Global:                               Variables and arrays.
  7654. * Go:                                   Room code.
  7655. * Go:                                   Vehicles.
  7656. * has:                                  Object definitions.
  7657. * has:                                  Attributes.
  7658. * HasLightSource:                       Library routines.
  7659. * HasLightSource(object):               Light.
  7660. * Headline:                             Library constants.
  7661. * if:                                   Blocks of code.
  7662. * InDefArt:                             Library routines.
  7663. * InDefArt(obj):                        Printing of names.
  7664. * INDENT_BIT:                           Lists.
  7665. * indirect:                             Crashes.
  7666. * initial:                              Library properties.
  7667. * initial:                              Simple objects.
  7668. * initial:                              Library properties.
  7669. * initial:                              Variables and arrays.
  7670. * Initialise:                           The player.
  7671. * Initialise:                           Shell.
  7672. * Initialise:                           Library entry points.
  7673. * Initialise:                           Each turn.
  7674. * Initialise:                           Library entry points.
  7675. * initstr:                              Variables and arrays.
  7676. * initstr:                              Variables and arrays.
  7677. * InScope:                              Library entry points.
  7678. * Insert:                               Basic containers.
  7679. * invent:                               Changing lists.
  7680. * invent:                               Library properties.
  7681. * inventory_stage:                      Changing lists.
  7682. * in_obj:                               Library objects.
  7683. * ITGONE_PE:                            Parser errors.
  7684. * jump:                                 Labels.
  7685. * JUNKAFTER_PE:                         Parser errors.
  7686. * Kiss:                                 Creatures.
  7687. * last:                                 Extending.
  7688. * LetGo:                                Basic containers.
  7689. * life:                                 Creatures.
  7690. * life:                                 Library properties.
  7691. * light:                                Library attributes.
  7692. * light:                                Attributes.
  7693. * location:                             The player.
  7694. * lockable:                             Library attributes.
  7695. * locked:                               Library attributes.
  7696. * locked:                               Basic containers.
  7697. * long:                                 Properties.
  7698. * LookRoutine:                          Library entry points.
  7699. * Lowstring:                            Answer (reflecting directions).
  7700. * MAX_CARRIED:                          Library constants.
  7701. * MAX_CARRIED:                          Max carried.
  7702. * MAX_SCORE:                            Library constants.
  7703. * MAX_SCORE:                            Score.
  7704. * MAX_SCORES:                           Score.
  7705. * MAX_TIMERS:                           Library constants.
  7706. * MAX_TIMERS:                           Timers.
  7707. * meta:                                 Library actions.
  7708. * meta:                                 Misc grammar.
  7709. * MMULTI_PE:                            Parser errors.
  7710. * move:                                 Object tree.
  7711. * moved:                                Library attributes.
  7712. * moved:                                Global scope.
  7713. * MULTI_PE:                             Parser errors.
  7714. * name:                                 Object definitions.
  7715. * name:                                 Naming of names.
  7716. * name:                                 Object definitions.
  7717. * name:                                 Library properties.
  7718. * Nearby:                               Object definitions.
  7719. * NEWLINE_BIT:                          Lists.
  7720. * NewRoom:                              Library entry points.
  7721. * NextWord:                             Numbers.
  7722. * NextWord:                             Library routines.
  7723. * ne_obj:                               Library objects.
  7724. * NOTHELD_PE:                           Parser errors.
  7725. * nothing:                              Object tree.
  7726. * nothing:                              Crashes.
  7727. * NOTHING_PE:                           Parser errors.
  7728. * notify_mode:                          Score.
  7729. * number:                               Library properties.
  7730. * NUMBER_PE:                            Parser errors.
  7731. * NUMBER_TASKS:                         Library constants.
  7732. * NUMBER_TASKS:                         Score.
  7733. * NUMBER_TASKS:                         Score.
  7734. * nw_obj:                               Library objects.
  7735. * n_obj:                                Library objects.
  7736. * Object:                               Object definitions.
  7737. * objectloop:                           Control constructs.
  7738. * OBJECT_SCORE:                         Library constants.
  7739. * OBJECT_SCORE:                         Score.
  7740. * OBJECT_SCORE:                         Score.
  7741. * OffersLight:                          Library routines.
  7742. * OffersLight(object):                  Light.
  7743. * on:                                   Switches.
  7744. * on:                                   Library attributes.
  7745. * open:                                 Library attributes.
  7746. * open:                                 Basic containers.
  7747. * openable:                             Basic containers.
  7748. * openable:                             Library attributes.
  7749. * or:                                   Conditions.
  7750. * Order:                                Creatures.
  7751. * out_obj:                              Library objects.
  7752. * parent:                               Crashes.
  7753. * parent:                               Object tree.
  7754. * parsed_number:                        Numbers.
  7755. * ParseNumber:                          Library entry points.
  7756. * ParseNumber:                          Numbers.
  7757. * ParserError:                          Library entry points.
  7758. * ParserError:                          Parser errors.
  7759. * parser_action:                        Plural names.
  7760. * parser_one:                           Plural names.
  7761. * parser_two:                           Plural names.
  7762. * parse_name:                           Plural names.
  7763. * parse_name:                           Naming of names.
  7764. * parse_name:                           Library properties.
  7765. * PARTINV_BIT:                          Lists.
  7766. * PlaceInScope:                         Changing scope.
  7767. * PlaceInScope:                         Library routines.
  7768. * PlayerTo:                             The player.
  7769. * PlayerTo:                             Crashes.
  7770. * PlayerTo:                             Library routines.
  7771. * plural:                               Plural names.
  7772. * plural:                               Library properties.
  7773. * print:                                Room code.
  7774. * print object:                         Printing of names.
  7775. * print object:                         Crashes.
  7776. * PrintRank:                            Library entry points.
  7777. * PrintRank:                            Score.
  7778. * PrintShortName:                       Library routines.
  7779. * PrintShortName(obj):                  Printing of names.
  7780. * PrintTaskName:                        Library entry points.
  7781. * PrintVerb:                            Misc grammar.
  7782. * PrintVerb:                            Library entry points.
  7783. * print_addr:                           Crashes.
  7784. * print_paddr:                          Crashes.
  7785. * proper:                               Printing of names.
  7786. * proper:                               Library attributes.
  7787. * Property:                             Properties.
  7788. * PushDir:                              Vehicles.
  7789. * random:                               Crashes.
  7790. * read_char:                            Dirty tricks.
  7791. * Receive:                              Basic containers.
  7792. * RECURSE_BIT:                          Lists.
  7793. * Remove:                               Basic containers.
  7794. * Replace:                              Replace.
  7795. * replace:                              Extending.
  7796. * ROOM_SCORE:                           Score.
  7797. * ROOM_SCORE:                           Score.
  7798. * ROOM_SCORE:                           Library constants.
  7799. * SACK_OBJECT:                          Library constants.
  7800. * SACK_OBJECT:                          Max carried.
  7801. * scenery:                              Library attributes.
  7802. * scenery:                              Map.
  7803. * SCENERY_PE:                           Parser errors.
  7804. * ScopeWithin:                          Library routines.
  7805. * ScopeWithin:                          Library routines.
  7806. * scope_stage:                          Changing scope.
  7807. * scored:                               Library attributes.
  7808. * Search:                               Library actions.
  7809. * self:                                 Causing actions.
  7810. * selfobj:                              Library objects.
  7811. * selfobj:                              Control constructs.
  7812. * SetTime:                              Each turn.
  7813. * SetTime:                              Library routines.
  7814. * set_cursor:                           Dirty tricks.
  7815. * set_window:                           Dirty tricks.
  7816. * se_obj:                               Library objects.
  7817. * short_name:                           Naming of names.
  7818. * short_name:                           Library properties.
  7819. * Show:                                 Creatures.
  7820. * sibling:                              Object tree.
  7821. * sp:                                   Variables and arrays.
  7822. * special_number:                       Creatures.
  7823. * special_word:                         Creatures.
  7824. * split_window:                         Dirty tricks.
  7825. * StartDaemon:                          Library routines.
  7826. * StartDaemon:                          About daemons.
  7827. * StartTimer:                           Library routines.
  7828. * StartTimer:                           Timers.
  7829. * static:                               Library attributes.
  7830. * static:                               Doors.
  7831. * Statusline:                           Each turn.
  7832. * StopDaemon:                           About daemons.
  7833. * StopDaemon:                           Library routines.
  7834. * StopTimer:                            Timers.
  7835. * StopTimer:                            Library routines.
  7836. * Story:                                Library constants.
  7837. * string:                               Variables and arrays.
  7838. * String:                               Answer (reflecting directions).
  7839. * STUCK_PE:                             Parser errors.
  7840. * style:                                Styles.
  7841. * supporter:                            Library attributes.
  7842. * supporter:                            Basic containers.
  7843. * supporter:                            Vehicles.
  7844. * switchable:                           Library attributes.
  7845. * switchable:                           Switches.
  7846. * sw_obj:                               Library objects.
  7847. * sw__var:                              Object definitions.
  7848. * s_obj:                                Library objects.
  7849. * talkable:                             Library attributes.
  7850. * TASKS_PROVIDED:                       Score.
  7851. * TASKS_PROVIDED:                       Library constants.
  7852. * task_scores:                          Score.
  7853. * TERSE_BIT:                            Lists.
  7854. * thedark:                              The player.
  7855. * thedark:                              Library objects.
  7856. * TheSame:                              Plural names.
  7857. * the_time:                             Each turn.
  7858. * ThrowAt:                              Creatures.
  7859. * ThrowAt:                              Creatures.
  7860. * TimePasses:                           Library entry points.
  7861. * time_left:                            Library properties.
  7862. * time_out:                             Library properties.
  7863. * time_out:                             Timers.
  7864. * TOOFEW_PE:                            Parser errors.
  7865. * TOOLIT_PE:                            Parser errors.
  7866. * top_object:                           Control constructs.
  7867. * transparent:                          Other containers.
  7868. * transparent:                          Creatures.
  7869. * transparent:                          Library attributes.
  7870. * transparent:                          Basic containers.
  7871. * TryNumber:                            Library routines.
  7872. * UnknownVerb:                          Misc grammar.
  7873. * UnknownVerb:                          Library entry points.
  7874. * UPTO_PE:                              Parser errors.
  7875. * u_obj:                                Library objects.
  7876. * VAGUE_PE:                             Parser errors.
  7877. * Verb:                                 New verbs.
  7878. * VERB_PE:                              Parser errors.
  7879. * visited:                              Library attributes.
  7880. * when_closed:                          Doors.
  7881. * when_closed:                          Library properties.
  7882. * when_off:                             Library properties.
  7883. * when_on:                              Library properties.
  7884. * when_open:                            Library properties.
  7885. * when_open:                            Doors.
  7886. * with:                                 Object definitions.
  7887. * with_key:                             Library properties.
  7888. * with_key:                             Lockable containers.
  7889. * wn:                                   Numbers.
  7890. * workflag:                             Library attributes.
  7891. * WORKFLAG_BIT:                         Lists.
  7892. * worn:                                 Library attributes.
  7893. * WriteListFrom:                        Library routines.
  7894. * WriteListFrom:                        Lists.
  7895. * w_obj:                                Library objects.
  7896. * YesOrNo:                              Library routines.
  7897. * YesOrNo:                              Yes or no.
  7898. * younger:                              Object tree.
  7899. * youngest:                             Object tree.
  7900.  
  7901.